1use std::iter;
2
3use rustc_data_structures::fx::FxIndexSet;
4use rustc_errors::{
5 Applicability, Diag, E0309, E0310, E0311, E0803, Subdiagnostic, msg, struct_span_code_err,
6};
7use rustc_hir::def::{DefKind, Namespace};
8use rustc_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::intravisit::Visitor;
10use rustc_hir::{self as hir, ParamName};
11use rustc_middle::traits::ObligationCauseCode;
12use rustc_middle::ty::error::TypeError;
13use rustc_middle::ty::print::RegionHighlightMode;
14use rustc_middle::ty::{
15 self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _, Upcast as _,
16};
17use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol, bug, kw, sym};
18use tracing::{debug, instrument};
19
20use super::ObligationCauseAsDiagArg;
21use super::nice_region_error::find_anon_type;
22use crate::diagnostics::{
23 self, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
24 RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, note_and_explain,
25};
26use crate::error_reporting::TypeErrCtxt;
27use crate::error_reporting::infer::ObligationCauseExt;
28use crate::error_reporting::infer::nice_region_error::placeholder_error::Highlighted;
29use crate::infer::region_constraints::GenericKind;
30use crate::infer::{
31 BoundRegionConversionTime, InferCtxt, RegionResolutionError, RegionVariableOrigin,
32 SubregionOrigin,
33};
34
35impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
36 pub fn report_region_errors(
37 &self,
38 generic_param_scope: LocalDefId,
39 errors: &[RegionResolutionError<'tcx>],
40 ) -> ErrorGuaranteed {
41 if !!errors.is_empty() {
::core::panicking::panic("assertion failed: !errors.is_empty()")
};assert!(!errors.is_empty());
42
43 if let Some(guaranteed) = self.infcx.tainted_by_errors() {
44 return guaranteed;
45 }
46
47 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:47",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(47u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_region_errors(): {0} errors to start",
errors.len()) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_region_errors(): {} errors to start", errors.len());
48
49 let errors = self.process_errors(errors);
52
53 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:53",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(53u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_region_errors: {0} errors after preprocessing",
errors.len()) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_region_errors: {} errors after preprocessing", errors.len());
54
55 let mut guar = None;
56 for error in errors {
57 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:57",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(57u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_region_errors: error = {0:?}",
error) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_region_errors: error = {:?}", error);
58
59 let e = if let Some(guar) =
60 self.try_report_nice_region_error(generic_param_scope, &error)
61 {
62 guar
63 } else {
64 match error.clone() {
65 RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
73 if sub.is_placeholder() || sup.is_placeholder() {
74 self.report_placeholder_failure(generic_param_scope, origin, sub, sup)
75 .emit_err()
76 } else {
77 self.report_concrete_failure(generic_param_scope, origin, sub, sup)
78 .emit_err()
79 }
80 }
81
82 RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self
83 .report_generic_bound_failure(
84 generic_param_scope,
85 origin.span(),
86 Some(origin),
87 param_ty,
88 sub,
89 ),
90
91 RegionResolutionError::SubSupConflict(
92 _,
93 var_origin,
94 sub_origin,
95 sub_r,
96 sup_origin,
97 sup_r,
98 _,
99 ) => {
100 if sub_r.is_placeholder() {
101 self.report_placeholder_failure(
102 generic_param_scope,
103 sub_origin,
104 sub_r,
105 sup_r,
106 )
107 .emit_err()
108 } else if sup_r.is_placeholder() {
109 self.report_placeholder_failure(
110 generic_param_scope,
111 sup_origin,
112 sub_r,
113 sup_r,
114 )
115 .emit_err()
116 } else {
117 self.report_sub_sup_conflict(
118 generic_param_scope,
119 var_origin,
120 sub_origin,
121 sub_r,
122 sup_origin,
123 sup_r,
124 )
125 }
126 }
127
128 RegionResolutionError::UpperBoundUniverseConflict(
129 _,
130 _,
131 _,
132 sup_origin,
133 sup_r,
134 ) => {
135 if !sup_r.is_placeholder() {
::core::panicking::panic("assertion failed: sup_r.is_placeholder()")
};assert!(sup_r.is_placeholder());
136
137 let sub_r = self.tcx.lifetimes.re_erased;
143
144 self.report_placeholder_failure(
145 generic_param_scope,
146 sup_origin,
147 sub_r,
148 sup_r,
149 )
150 .emit_err()
151 }
152
153 RegionResolutionError::CannotNormalize(clause, origin) => {
154 let clause: ty::Clause<'tcx> =
155 clause.map_bound(ty::ClauseKind::TypeOutlives).upcast(self.tcx);
156 self.tcx
157 .dcx()
158 .struct_span_err(origin.span(), ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("cannot normalize `{0}`", clause))
})format!("cannot normalize `{clause}`"))
159 .emit_err()
160 }
161 }
162 };
163
164 guar = Some(e)
165 }
166
167 guar.unwrap()
168 }
169
170 fn process_errors(
181 &self,
182 errors: &[RegionResolutionError<'tcx>],
183 ) -> Vec<RegionResolutionError<'tcx>> {
184 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:184",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(184u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("process_errors()")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("process_errors()");
185
186 let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e {
199 RegionResolutionError::GenericBoundFailure(..) => true,
200 RegionResolutionError::ConcreteFailure(..)
201 | RegionResolutionError::SubSupConflict(..)
202 | RegionResolutionError::UpperBoundUniverseConflict(..)
203 | RegionResolutionError::CannotNormalize(..) => false,
204 };
205
206 let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
207 errors.to_owned()
208 } else {
209 errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
210 };
211
212 errors.sort_by_key(|u| {
214 match *u {
215 RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(),
216 RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(),
217 RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(),
218 RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => {
219 rvo.span()
220 }
221 RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(),
222 }
223 .lo_hi()
224 });
225 errors
226 }
227
228 pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
229 match *origin {
230 SubregionOrigin::Subtype(ref trace) => RegionOriginNote::WithRequirement {
231 span: trace.cause.span,
232 requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
233 expected_found: self.values_str(trace.values, &trace.cause, err.long_ty_path()),
234 }
235 .add_to_diag(err),
236 SubregionOrigin::Reborrow(span) => RegionOriginNote::Plain {
237 span,
238 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that reference does not outlive borrowed content"))msg!("...so that reference does not outlive borrowed content"),
239 }
240 .add_to_diag(err),
241 SubregionOrigin::RelateObjectBound(span) => {
242 RegionOriginNote::Plain {
243 span,
244 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that it can be closed over into an object"))msg!("...so that it can be closed over into an object"),
245 }
246 .add_to_diag(err);
247 }
248 SubregionOrigin::ReferenceOutlivesReferent(ty, span) => {
249 RegionOriginNote::WithName {
250 span,
251 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that the reference type `{$name}` does not outlive the data it points at"))msg!("...so that the reference type `{$name}` does not outlive the data it points at"),
252 name: &self.ty_to_string(ty),
253 continues: false,
254 }
255 .add_to_diag(err);
256 }
257 SubregionOrigin::RelateParamBound(span, ty, opt_span) => {
258 RegionOriginNote::WithName {
259 span,
260 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that the type `{$name}` will meet its required lifetime bounds{$continues ->\n [true] ...\n *[false] {\"\"}\n }"))msg!(
261 "...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
262 [true] ...
263 *[false] {\"\"}
264 }"
265 ),
266 name: &self.ty_to_string(ty),
267 continues: opt_span.is_some(),
268 }
269 .add_to_diag(err);
270 if let Some(span) = opt_span {
271 RegionOriginNote::Plain {
272 span,
273 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...that is required by this bound"))msg!("...that is required by this bound"),
274 }
275 .add_to_diag(err);
276 }
277 }
278 SubregionOrigin::RelateRegionParamBound(span, _) => {
279 RegionOriginNote::Plain {
280 span,
281 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that the declared lifetime parameter bounds are satisfied"))msg!("...so that the declared lifetime parameter bounds are satisfied"),
282 }
283 .add_to_diag(err);
284 }
285 SubregionOrigin::CompareImplItemObligation { span, .. } => {
286 RegionOriginNote::Plain {
287 span,
288 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that the definition in impl matches the definition from the trait"))msg!(
289 "...so that the definition in impl matches the definition from the trait"
290 ),
291 }
292 .add_to_diag(err);
293 }
294 SubregionOrigin::CheckAssociatedTypeBounds { ref parent, .. } => {
295 self.note_region_origin(err, parent);
296 }
297 SubregionOrigin::AscribeUserTypeProvePredicate(span, _) => {
298 RegionOriginNote::Plain { span, msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that the where clause holds"))msg!("...so that the where clause holds") }
299 .add_to_diag(err);
300 }
301 SubregionOrigin::SolverRegionConstraint(span) => {
302 RegionOriginNote::Plain {
303 span,
304 msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that a higher-ranked lifetime bound can be satisfied"))msg!("...so that a higher-ranked lifetime bound can be satisfied"),
305 }
306 .add_to_diag(err);
307 }
308 }
309 }
310
311 pub(super) fn report_concrete_failure(
312 &self,
313 generic_param_scope: LocalDefId,
314 origin: SubregionOrigin<'tcx>,
315 sub: Region<'tcx>,
316 sup: Region<'tcx>,
317 ) -> Diag<'a> {
318 let mut err = match origin {
319 SubregionOrigin::Subtype(trace) => {
320 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
321 let mut err = self.report_and_explain_type_error(
322 *trace,
323 self.tcx.param_env(generic_param_scope),
324 terr,
325 );
326 match (sub.kind(), sup.kind()) {
327 (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
328 (ty::RePlaceholder(_), _) => {
329 note_and_explain_region(
330 self.tcx,
331 &mut err,
332 generic_param_scope,
333 "",
334 sup,
335 " doesn't meet the lifetime requirements",
336 None,
337 );
338 }
339 (_, ty::RePlaceholder(_)) => {
340 note_and_explain_region(
341 self.tcx,
342 &mut err,
343 generic_param_scope,
344 "the required lifetime does not necessarily outlive ",
345 sub,
346 "",
347 None,
348 );
349 }
350 _ => {
351 note_and_explain_region(
352 self.tcx,
353 &mut err,
354 generic_param_scope,
355 "",
356 sup,
357 "...",
358 None,
359 );
360 note_and_explain_region(
361 self.tcx,
362 &mut err,
363 generic_param_scope,
364 "...does not necessarily outlive ",
365 sub,
366 "",
367 None,
368 );
369 }
370 }
371 err
372 }
373 SubregionOrigin::Reborrow(span) => {
374 let reference_valid = note_and_explain::RegionExplanation::new(
375 self.tcx,
376 generic_param_scope,
377 sub,
378 None,
379 note_and_explain::PrefixKind::RefValidFor,
380 note_and_explain::SuffixKind::Continues,
381 );
382 let content_valid = note_and_explain::RegionExplanation::new(
383 self.tcx,
384 generic_param_scope,
385 sup,
386 None,
387 note_and_explain::PrefixKind::ContentValidFor,
388 note_and_explain::SuffixKind::Empty,
389 );
390 self.dcx().create_err(OutlivesContent {
391 span,
392 notes: reference_valid.into_iter().chain(content_valid).collect(),
393 })
394 }
395 SubregionOrigin::RelateObjectBound(span) => {
396 let object_valid = note_and_explain::RegionExplanation::new(
397 self.tcx,
398 generic_param_scope,
399 sub,
400 None,
401 note_and_explain::PrefixKind::TypeObjValidFor,
402 note_and_explain::SuffixKind::Empty,
403 );
404 let pointer_valid = note_and_explain::RegionExplanation::new(
405 self.tcx,
406 generic_param_scope,
407 sup,
408 None,
409 note_and_explain::PrefixKind::SourcePointerValidFor,
410 note_and_explain::SuffixKind::Empty,
411 );
412 self.dcx().create_err(OutlivesBound {
413 span,
414 notes: object_valid.into_iter().chain(pointer_valid).collect(),
415 })
416 }
417 SubregionOrigin::RelateParamBound(span, ty, opt_span) => {
418 let prefix = match sub.kind() {
419 ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
420 _ => note_and_explain::PrefixKind::TypeOutlive,
421 };
422 let suffix = if opt_span.is_some() {
423 note_and_explain::SuffixKind::ReqByBinding
424 } else {
425 note_and_explain::SuffixKind::Empty
426 };
427 let note = note_and_explain::RegionExplanation::new(
428 self.tcx,
429 generic_param_scope,
430 sub,
431 opt_span,
432 prefix,
433 suffix,
434 );
435 self.dcx().create_err(FulfillReqLifetime {
436 span,
437 ty: self.deeply_resolve_ignoring_regions(ty),
438 note,
439 })
440 }
441 SubregionOrigin::RelateRegionParamBound(span, ty) => {
442 let param_instantiated = note_and_explain::RegionExplanation::new(
443 self.tcx,
444 generic_param_scope,
445 sup,
446 None,
447 note_and_explain::PrefixKind::LfParamInstantiatedWith,
448 note_and_explain::SuffixKind::Empty,
449 );
450 let mut alt_span = None;
451 if let Some(ty) = ty
452 && sub.is_static()
453 && let ty::Dynamic(preds, _) = ty.kind()
454 && let Some(def_id) = preds.principal_def_id()
455 {
456 for (clause, span) in
457 self.tcx.clauses_of(def_id).instantiate_identity(self.tcx).into_iter()
458 {
459 if let ty::ClauseKind::TypeOutlives(ty::OutlivesClause(a, b)) =
460 clause.kind().skip_binder()
461 && let ty::Param(param) = a.kind()
462 && param.name == kw::SelfUpper
463 && b.is_static()
464 {
465 alt_span = Some(span);
467 }
468 }
469 }
470 let param_must_outlive = note_and_explain::RegionExplanation::new(
471 self.tcx,
472 generic_param_scope,
473 sub,
474 alt_span,
475 note_and_explain::PrefixKind::LfParamMustOutlive,
476 note_and_explain::SuffixKind::Empty,
477 );
478 self.dcx().create_err(LfBoundNotSatisfied {
479 span,
480 notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
481 })
482 }
483 SubregionOrigin::ReferenceOutlivesReferent(ty, span) => {
484 let pointer_valid = note_and_explain::RegionExplanation::new(
485 self.tcx,
486 generic_param_scope,
487 sub,
488 None,
489 note_and_explain::PrefixKind::PointerValidFor,
490 note_and_explain::SuffixKind::Empty,
491 );
492 let data_valid = note_and_explain::RegionExplanation::new(
493 self.tcx,
494 generic_param_scope,
495 sup,
496 None,
497 note_and_explain::PrefixKind::DataValidFor,
498 note_and_explain::SuffixKind::Empty,
499 );
500 self.dcx().create_err(RefLongerThanData {
501 span,
502 ty: self.deeply_resolve_ignoring_regions(ty),
503 notes: pointer_valid.into_iter().chain(data_valid).collect(),
504 })
505 }
506 SubregionOrigin::CompareImplItemObligation {
507 span,
508 impl_item_def_id,
509 trait_item_def_id,
510 } => {
511 let mut err = self.report_extra_impl_obligation(
512 span,
513 impl_item_def_id,
514 trait_item_def_id,
515 &::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}: {1}`", sup, sub))
})format!("`{sup}: {sub}`"),
516 );
517 if let Some(generics) = self.tcx.hir_get_generics(impl_item_def_id)
519 && generics.where_clause_span.contains(span)
520 {
521 self.suggest_copy_trait_method_bounds(
522 trait_item_def_id,
523 impl_item_def_id,
524 &mut err,
525 );
526 }
527 err
528 }
529 SubregionOrigin::CheckAssociatedTypeBounds {
530 impl_item_def_id,
531 trait_item_def_id,
532 parent,
533 } => {
534 let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
535
536 if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
539 let trait_item_span = self.tcx.def_span(trait_item_def_id);
540 let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
541 err.span_label(
542 trait_item_span,
543 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("definition of `{0}` from trait",
item_name))
})format!("definition of `{item_name}` from trait"),
544 );
545 }
546
547 self.suggest_copy_trait_method_bounds(
548 trait_item_def_id,
549 impl_item_def_id,
550 &mut err,
551 );
552 err
553 }
554 SubregionOrigin::AscribeUserTypeProvePredicate(span, _) => {
555 let instantiated = note_and_explain::RegionExplanation::new(
556 self.tcx,
557 generic_param_scope,
558 sup,
559 None,
560 note_and_explain::PrefixKind::LfInstantiatedWith,
561 note_and_explain::SuffixKind::Empty,
562 );
563 let must_outlive = note_and_explain::RegionExplanation::new(
564 self.tcx,
565 generic_param_scope,
566 sub,
567 None,
568 note_and_explain::PrefixKind::LfMustOutlive,
569 note_and_explain::SuffixKind::Empty,
570 );
571 self.dcx().create_err(LfBoundNotSatisfied {
572 span,
573 notes: instantiated.into_iter().chain(must_outlive).collect(),
574 })
575 }
576 SubregionOrigin::SolverRegionConstraint(span) => self
577 .dcx()
578 .struct_span_err(span, "higher-ranked lifetime bound could not be satisfied"),
579 };
580 if sub.is_error() || sup.is_error() {
581 err.downgrade_to_delayed_bug();
582 }
583 err
584 }
585
586 pub fn suggest_copy_trait_method_bounds(
587 &self,
588 trait_item_def_id: DefId,
589 impl_item_def_id: LocalDefId,
590 err: &mut Diag<'_>,
591 ) {
592 let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(impl_item_def_id.to_def_id()) else {
598 return;
599 };
600 let trait_ref = self.tcx.impl_trait_ref(impl_def_id);
601 let trait_args = trait_ref
602 .instantiate_identity()
603 .skip_norm_wip()
604 .with_replaced_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
606 .args;
607 let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
608 .rebase_onto(self.tcx, impl_def_id, trait_args);
609
610 let Ok(trait_predicates) = self
611 .tcx
612 .explicit_clauses_of(trait_item_def_id)
613 .instantiate_own(self.tcx, trait_item_args)
614 .map(|(clause, _)| {
615 let clause = clause.skip_norm_wip();
616 if clause.is_suggestable(self.tcx, false) {
617 Ok(clause.to_string())
618 } else {
619 Err(())
620 }
621 })
622 .collect::<Result<Vec<_>, ()>>()
623 else {
624 return;
625 };
626
627 let Some(generics) = self.tcx.hir_get_generics(impl_item_def_id) else {
628 return;
629 };
630
631 let suggestion = if trait_predicates.is_empty() {
632 WhereClauseSuggestions::Remove { span: generics.where_clause_span }
633 } else {
634 let space = if generics.where_clause_span.is_empty() { " " } else { "" };
635 WhereClauseSuggestions::CopyPredicates {
636 span: generics.where_clause_span,
637 space,
638 trait_predicates: trait_predicates.join(", "),
639 }
640 };
641 err.subdiagnostic(suggestion);
642 }
643
644 pub(super) fn report_placeholder_failure(
645 &self,
646 generic_param_scope: LocalDefId,
647 placeholder_origin: SubregionOrigin<'tcx>,
648 sub: Region<'tcx>,
649 sup: Region<'tcx>,
650 ) -> Diag<'a> {
651 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:652",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(652u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("placeholder_origin")
}> =
::tracing::__macro_support::FieldName::new("placeholder_origin");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("sub")
}> =
::tracing::__macro_support::FieldName::new("sub");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("sup")
}> =
::tracing::__macro_support::FieldName::new("sup");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_placeholder_failure")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&placeholder_origin)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sub)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sup)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
653 match placeholder_origin {
654 SubregionOrigin::Subtype(ref trace)
655 if #[allow(non_exhaustive_omitted_patterns)] match &trace.cause.code().peel_derives()
{
ObligationCauseCode::WhereClause(..) |
ObligationCauseCode::WhereClauseInExpr(..) => true,
_ => false,
}matches!(
656 &trace.cause.code().peel_derives(),
657 ObligationCauseCode::WhereClause(..)
658 | ObligationCauseCode::WhereClauseInExpr(..)
659 ) =>
660 {
661 if let ObligationCauseCode::WhereClause(_, span)
663 | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
664 &trace.cause.code().peel_derives()
665 {
666 let span = *span;
667 let mut err = self.report_concrete_failure(
668 generic_param_scope,
669 placeholder_origin,
670 sub,
671 sup,
672 );
673 if !span.is_dummy() {
674 err =
675 err.with_span_note(span, "the lifetime requirement is introduced here");
676 }
677 err
678 } else {
679 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here...")));
}unreachable!(
680 "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
681 )
682 }
683 }
684 SubregionOrigin::Subtype(trace) => {
685 let terr = TypeError::RegionsPlaceholderMismatch;
686 return self.report_and_explain_type_error(
687 *trace,
688 self.tcx.param_env(generic_param_scope),
689 terr,
690 );
691 }
692 _ => {
693 return self.report_concrete_failure(
694 generic_param_scope,
695 placeholder_origin,
696 sub,
697 sup,
698 );
699 }
700 }
701 }
702
703 pub fn report_generic_bound_failure(
704 &self,
705 generic_param_scope: LocalDefId,
706 span: Span,
707 origin: Option<SubregionOrigin<'tcx>>,
708 bound_kind: GenericKind<'tcx>,
709 sub: Region<'tcx>,
710 ) -> ErrorGuaranteed {
711 self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub)
712 .emit_err()
713 }
714
715 pub fn construct_generic_bound_failure(
716 &self,
717 generic_param_scope: LocalDefId,
718 span: Span,
719 origin: Option<SubregionOrigin<'tcx>>,
720 bound_kind: GenericKind<'tcx>,
721 sub: Region<'tcx>,
722 ) -> Diag<'a> {
723 if let Some(SubregionOrigin::CompareImplItemObligation {
724 span,
725 impl_item_def_id,
726 trait_item_def_id,
727 }) = origin
728 {
729 return self.report_extra_impl_obligation(
730 span,
731 impl_item_def_id,
732 trait_item_def_id,
733 &::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}: {1}`", bound_kind, sub))
})format!("`{bound_kind}: {sub}`"),
734 );
735 }
736
737 let labeled_user_string = match bound_kind {
738 GenericKind::Param(_) => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the parameter type `{0}`",
bound_kind))
})format!("the parameter type `{bound_kind}`"),
739 GenericKind::Placeholder(_) => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the placeholder type `{0}`",
bound_kind))
})format!("the placeholder type `{bound_kind}`"),
740 GenericKind::Alias(p) => match p.kind {
741 ty::Projection { .. } | ty::Inherent { .. } => {
742 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the associated type `{0}`",
bound_kind))
})format!("the associated type `{bound_kind}`")
743 }
744 ty::Free { .. } => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the type alias `{0}`", bound_kind))
})format!("the type alias `{bound_kind}`"),
745 ty::Opaque { .. } => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the opaque type `{0}`",
bound_kind))
})format!("the opaque type `{bound_kind}`"),
746 },
747 };
748
749 let mut err = self
750 .tcx
751 .dcx()
752 .struct_span_err(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} may not live long enough",
labeled_user_string))
})format!("{labeled_user_string} may not live long enough"));
753 err.code(match sub.kind() {
754 ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.is_named(self.tcx) => E0309,
755 ty::ReStatic => E0310,
756 _ => E0311,
757 });
758
759 '_explain: {
760 let (description, span) = match sub.kind() {
761 ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
762 msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span))
763 }
764 _ => (::alloc::__export::must_use({
::alloc::fmt::format(format_args!("lifetime `{0}`", sub))
})format!("lifetime `{sub}`"), Some(span)),
765 };
766 let prefix = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} must be valid for ",
labeled_user_string))
})format!("{labeled_user_string} must be valid for ");
767 label_msg_span(&mut err, &prefix, description, span, "...");
768 if let Some(origin) = origin {
769 self.note_region_origin(&mut err, &origin);
770 }
771 }
772
773 'suggestion: {
774 let msg = "consider adding an explicit lifetime bound";
775
776 if (bound_kind, sub).has_infer_regions()
777 || (bound_kind, sub).has_placeholders()
778 || !bound_kind.is_suggestable(self.tcx, false)
779 {
780 let lt_name = sub.get_name_or_anon(self.tcx).to_string();
781 err.help(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} `{1}: {2}`...", msg,
bound_kind, lt_name))
})format!("{msg} `{bound_kind}: {lt_name}`..."));
782 break 'suggestion;
783 }
784
785 let mut generic_param_scope = generic_param_scope;
786 while self.tcx.def_kind(generic_param_scope) == DefKind::OpaqueTy {
787 generic_param_scope = self.tcx.local_parent(generic_param_scope);
788 }
789
790 let (type_scope, type_param_sugg_span) = match bound_kind {
792 GenericKind::Param(param) => {
793 let generics = self.tcx.generics_of(generic_param_scope);
794 let type_param = generics.type_param(param, self.tcx);
795 let def_id = type_param.def_id.expect_local();
796 let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id;
797 let hir_generics = self.tcx.hir_get_generics(scope).unwrap();
801 let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) {
802 Some((span, open_paren_sp)) => {
803 Some((span, LifetimeSuggestion::NeedsPlus(open_paren_sp)))
804 }
805 None if generics.has_self && param.index == 0 => None,
807 None => {
808 let mut colon_flag = false;
809 let span = if let Some(param) =
810 hir_generics.params.iter().find(|param| param.def_id == def_id)
811 && let ParamName::Plain(ident) = param.name
812 {
813 if let Some(sp) = param.colon_span {
814 colon_flag = true;
815 sp.shrink_to_hi()
816 } else {
817 ident.span.shrink_to_hi()
818 }
819 } else {
820 let span = self.tcx.def_span(def_id);
821 span.shrink_to_hi()
822 };
823 match colon_flag {
824 true => Some((span, LifetimeSuggestion::HasColon)),
825 false => Some((span, LifetimeSuggestion::NeedsColon)),
826 }
827 }
828 };
829 (scope, sugg_span)
830 }
831 _ => (generic_param_scope, None),
832 };
833 let suggestion_scope = {
834 let lifetime_scope = match sub.kind() {
835 ty::ReStatic => hir::def_id::CRATE_DEF_ID,
836 _ => match self.tcx.is_suitable_region(generic_param_scope, sub) {
837 Some(info) => info.scope,
838 None => generic_param_scope,
839 },
840 };
841 match self.tcx.is_descendant_of(type_scope, lifetime_scope) {
842 true => type_scope,
843 false => lifetime_scope,
844 }
845 };
846
847 let mut suggs = ::alloc::vec::Vec::new()vec![];
848 let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs);
849
850 if let Some((sp, suggestion_type)) = type_param_sugg_span
851 && suggestion_scope == type_scope
852 {
853 match suggestion_type {
854 LifetimeSuggestion::NeedsPlus(open_paren_sp) => {
855 let suggestion = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" + {0}", lt_name))
})format!(" + {lt_name}");
856 if let Some(open_paren_sp) = open_paren_sp {
857 suggs.push((open_paren_sp, "(".to_string()));
858 suggs.push((sp, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("){0}", suggestion))
})format!("){suggestion}")));
859 } else {
860 suggs.push((sp, suggestion));
861 }
862 }
863 LifetimeSuggestion::NeedsColon => suggs.push((sp, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(": {0}", lt_name))
})format!(": {lt_name}"))),
864 LifetimeSuggestion::HasColon => suggs.push((sp, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}", lt_name))
})format!(" {lt_name}"))),
865 }
866 } else if let GenericKind::Alias(ref p) = bound_kind
867 && let ty::Projection { def_id } = p.kind
868 && let DefKind::AssocTy = self.tcx.def_kind(def_id)
869 && let Some(ty::ImplTraitInTraitData::Trait { .. }) =
870 self.tcx.opt_rpitit_info(def_id)
871 {
872 } else if let Some(generics) = self.tcx.hir_get_generics(suggestion_scope) {
875 let pred = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}: {1}", bound_kind, lt_name))
})format!("{bound_kind}: {lt_name}");
876 let suggestion = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} {1}",
generics.add_where_or_trailing_comma(), pred))
})format!("{} {}", generics.add_where_or_trailing_comma(), pred);
877 suggs.push((generics.tail_span_for_predicate_suggestion(), suggestion))
878 } else {
879 let consider = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} `{1}: {2}`...", msg,
bound_kind, sub))
})format!("{msg} `{bound_kind}: {sub}`...");
880 err.help(consider);
881 }
882
883 if !suggs.is_empty() {
884 err.multipart_suggestion(
885 msg,
886 suggs,
887 Applicability::MaybeIncorrect, );
889 }
890 }
891
892 if sub.kind() == ty::ReStatic
893 && let Some(node) = self.tcx.hir_get_if_local(generic_param_scope.into())
894 && let hir::Node::Item(hir::Item {
895 kind: hir::ItemKind::Fn { sig, body, has_body: true, .. },
896 ..
897 })
898 | hir::Node::TraitItem(hir::TraitItem {
899 kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)),
900 ..
901 })
902 | hir::Node::ImplItem(hir::ImplItem {
903 kind: hir::ImplItemKind::Fn(sig, body), ..
904 }) = node
905 && let hir::Node::Expr(expr) = self.tcx.hir_node(body.hir_id)
906 && let hir::ExprKind::Block(block, _) = expr.kind
907 && let Some(tail) = block.expr
908 && tail.span == span
909 && let hir::FnRetTy::Return(ty) = sig.decl.output
910 && let hir::TyKind::Path(path) = ty.kind
911 && let hir::QPath::Resolved(None, path) = path
912 && let hir::def::Res::Def(_, def_id) = path.res
913 && Some(def_id) == self.tcx.lang_items().owned_box()
914 && let [segment] = path.segments
915 && let Some(args) = segment.args
916 && let [hir::GenericArg::Type(ty)] = args.args
917 && let hir::TyKind::TraitObject(_, tagged_ref) = ty.kind
918 && let hir::LifetimeKind::ImplicitObjectLifetimeDefault = tagged_ref.pointer().kind
919 {
920 err.span_label(
923 ty.span,
924 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("this `dyn Trait` has an implicit `\'static` lifetime bound"))
})format!("this `dyn Trait` has an implicit `'static` lifetime bound"),
925 );
926 }
927
928 err
929 }
930
931 pub fn suggest_name_region(
932 &self,
933 generic_param_scope: LocalDefId,
934 lifetime: Region<'tcx>,
935 add_lt_suggs: &mut Vec<(Span, String)>,
936 ) -> String {
937 struct LifetimeReplaceVisitor<'a> {
938 needle: hir::LifetimeKind,
939 new_lt: &'a str,
940 add_lt_suggs: &'a mut Vec<(Span, String)>,
941 }
942
943 impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> {
944 fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
945 if lt.kind == self.needle {
946 self.add_lt_suggs.push(lt.suggestion(self.new_lt));
947 }
948 }
949 }
950
951 let (lifetime_def_id, lifetime_scope) =
952 match self.tcx.is_suitable_region(generic_param_scope, lifetime) {
953 Some(info) if !lifetime.is_named(self.tcx) => {
954 (info.region_def_id.expect_local(), info.scope)
955 }
956 _ => return lifetime.get_name_or_anon(self.tcx).to_string(),
957 };
958
959 let new_lt = {
960 let generics = self.tcx.generics_of(lifetime_scope);
961 let mut used_names =
962 iter::successors(Some(generics), |g| g.parent.map(|p| self.tcx.generics_of(p)))
963 .flat_map(|g| &g.own_params)
964 .filter(|p| #[allow(non_exhaustive_omitted_patterns)] match p.kind {
ty::GenericParamDefKind::Lifetime => true,
_ => false,
}matches!(p.kind, ty::GenericParamDefKind::Lifetime))
965 .map(|p| p.name)
966 .collect::<Vec<_>>();
967 let hir_id = self.tcx.local_def_id_to_hir_id(lifetime_scope);
968 used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map(
970 |p| match p {
971 ty::BoundVariableKind::Region(lt) => lt.get_name(self.tcx),
972 _ => None,
973 },
974 ));
975 (b'a'..=b'z')
976 .map(|c| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("\'{0}", c as char))
})format!("'{}", c as char))
977 .find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate))
978 .unwrap_or_else(|| "'lt".to_string())
979 };
980
981 let mut visitor = LifetimeReplaceVisitor {
982 needle: hir::LifetimeKind::Param(lifetime_def_id),
983 add_lt_suggs,
984 new_lt: &new_lt,
985 };
986 match self.tcx.expect_hir_owner_node(lifetime_scope) {
987 hir::OwnerNode::Item(i) => visitor.visit_item(i),
988 hir::OwnerNode::ForeignItem(i) => visitor.visit_foreign_item(i),
989 hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i),
990 hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i),
991 hir::OwnerNode::Crate(_) => ::rustc_span::macros::bug_impl(None,
format_args!("OwnerNode::Crate doesn\'t not have generics"),
Location::caller())bug!("OwnerNode::Crate doesn't not have generics"),
992 hir::OwnerNode::Synthetic => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
993 }
994
995 let ast_generics = self.tcx.hir_get_generics(lifetime_scope).unwrap();
996 let sugg = ast_generics
997 .span_for_lifetime_suggestion()
998 .map(|span| (span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}, ", new_lt))
})format!("{new_lt}, ")))
999 .unwrap_or_else(|| (ast_generics.span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{0}>", new_lt))
})format!("<{new_lt}>")));
1000 add_lt_suggs.push(sugg);
1001
1002 new_lt
1003 }
1004
1005 fn report_sub_sup_conflict(
1006 &self,
1007 generic_param_scope: LocalDefId,
1008 var_origin: RegionVariableOrigin<'tcx>,
1009 sub_origin: SubregionOrigin<'tcx>,
1010 sub_region: Region<'tcx>,
1011 sup_origin: SubregionOrigin<'tcx>,
1012 sup_region: Region<'tcx>,
1013 ) -> ErrorGuaranteed {
1014 let mut err = self.report_inference_failure(var_origin);
1015
1016 note_and_explain_region(
1017 self.tcx,
1018 &mut err,
1019 generic_param_scope,
1020 "first, the lifetime cannot outlive ",
1021 sup_region,
1022 "...",
1023 None,
1024 );
1025
1026 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1026",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(1026u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: var_origin={0:?}",
var_origin) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
1027 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1027",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(1027u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sub_region={0:?}",
sub_region) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
1028 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1028",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(1028u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sub_origin={0:?}",
sub_origin) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
1029 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1029",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(1029u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sup_region={0:?}",
sup_region) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
1030 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1030",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(1030u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sup_origin={0:?}",
sup_origin) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
1031
1032 if let SubregionOrigin::Subtype(ref sup_trace) = sup_origin
1033 && let SubregionOrigin::Subtype(ref sub_trace) = sub_origin
1034 && let Some((sup_expected, sup_found)) =
1035 self.values_str(sup_trace.values, &sup_trace.cause, err.long_ty_path())
1036 && let Some((sub_expected, sub_found)) =
1037 self.values_str(sub_trace.values, &sub_trace.cause, err.long_ty_path())
1038 && sub_expected == sup_expected
1039 && sub_found == sup_found
1040 {
1041 note_and_explain_region(
1042 self.tcx,
1043 &mut err,
1044 generic_param_scope,
1045 "...but the lifetime must also be valid for ",
1046 sub_region,
1047 "...",
1048 None,
1049 );
1050 err.span_note(
1051 sup_trace.cause.span,
1052 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("...so that the {0}",
sup_trace.cause.as_requirement_str()))
})format!("...so that the {}", sup_trace.cause.as_requirement_str()),
1053 );
1054
1055 err.note_expected_found("", sup_expected, "", sup_found);
1056 return if sub_region.is_error() | sup_region.is_error() {
1057 err.delay_as_bug()
1058 } else {
1059 err.emit_err()
1060 };
1061 }
1062
1063 self.note_region_origin(&mut err, &sup_origin);
1064
1065 note_and_explain_region(
1066 self.tcx,
1067 &mut err,
1068 generic_param_scope,
1069 "but, the lifetime must be valid for ",
1070 sub_region,
1071 "...",
1072 None,
1073 );
1074
1075 self.note_region_origin(&mut err, &sub_origin);
1076 if sub_region.is_error() | sup_region.is_error() {
1077 err.delay_as_bug()
1078 } else {
1079 err.emit_err()
1080 }
1081 }
1082
1083 fn report_inference_failure(&self, var_origin: RegionVariableOrigin<'tcx>) -> Diag<'_> {
1084 let br_string = |br: ty::BoundRegionKind<'tcx>| {
1085 let mut s = match br {
1086 ty::BoundRegionKind::Named(def_id) => self.tcx.item_name(def_id).to_string(),
1087 _ => String::new(),
1088 };
1089 if !s.is_empty() {
1090 s.push(' ');
1091 }
1092 s
1093 };
1094 let var_description = match var_origin {
1095 RegionVariableOrigin::Misc(_) => String::new(),
1096 RegionVariableOrigin::PatternRegion(_) => " for pattern".to_string(),
1097 RegionVariableOrigin::BorrowRegion(_) => " for borrow expression".to_string(),
1098 RegionVariableOrigin::Autoref(_) => " for autoref".to_string(),
1099 RegionVariableOrigin::Coercion(_) => " for automatic coercion".to_string(),
1100 RegionVariableOrigin::BoundRegion(_, br, BoundRegionConversionTime::FnCall) => {
1101 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" for lifetime parameter {0}in function call",
br_string(br)))
})format!(" for lifetime parameter {}in function call", br_string(br))
1102 }
1103 RegionVariableOrigin::BoundRegion(
1104 _,
1105 br,
1106 BoundRegionConversionTime::HigherRankedType,
1107 ) => {
1108 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" for lifetime parameter {0}in generic type",
br_string(br)))
})format!(" for lifetime parameter {}in generic type", br_string(br))
1109 }
1110 RegionVariableOrigin::BoundRegion(
1111 _,
1112 br,
1113 BoundRegionConversionTime::AssocTypeProjection(def_id),
1114 ) => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" for lifetime parameter {0}in trait containing associated type `{1}`",
br_string(br), self.tcx.associated_item(def_id).name()))
})format!(
1115 " for lifetime parameter {}in trait containing associated type `{}`",
1116 br_string(br),
1117 self.tcx.associated_item(def_id).name()
1118 ),
1119 RegionVariableOrigin::RegionParameterDefinition(_, name) => {
1120 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" for lifetime parameter `{0}`",
name))
})format!(" for lifetime parameter `{name}`")
1121 }
1122 RegionVariableOrigin::UpvarRegion(ref upvar_id, _) => {
1123 let var_name = self.tcx.hir_name(upvar_id.var_path.hir_id);
1124 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" for capture of `{0}` by closure",
var_name))
})format!(" for capture of `{var_name}` by closure")
1125 }
1126 RegionVariableOrigin::Nll(..) => ::rustc_span::macros::bug_impl(None,
format_args!("NLL variable found in lexical phase"), Location::caller())bug!("NLL variable found in lexical phase"),
1127 };
1128
1129 {
self.dcx().struct_span_err(var_origin.span(),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("cannot infer an appropriate lifetime{0} due to conflicting requirements",
var_description))
})).with_code(E0803)
}struct_span_code_err!(
1130 self.dcx(),
1131 var_origin.span(),
1132 E0803,
1133 "cannot infer an appropriate lifetime{} due to conflicting requirements",
1134 var_description
1135 )
1136 }
1137}
1138
1139enum LifetimeSuggestion {
1140 NeedsPlus(Option<Span>),
1141 NeedsColon,
1142 HasColon,
1143}
1144
1145pub(super) fn note_and_explain_region<'tcx>(
1146 tcx: TyCtxt<'tcx>,
1147 err: &mut Diag<'_>,
1148 generic_param_scope: LocalDefId,
1149 prefix: &str,
1150 region: ty::Region<'tcx>,
1151 suffix: &str,
1152 alt_span: Option<Span>,
1153) {
1154 let (description, span) = match region.kind() {
1155 ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
1156 msg_span_from_named_region(tcx, generic_param_scope, region, alt_span)
1157 }
1158
1159 ty::ReError(_) => return,
1160
1161 ty::ReVar(_) => (::alloc::__export::must_use({
::alloc::fmt::format(format_args!("lifetime `{0}`", region))
})format!("lifetime `{region}`"), alt_span),
1163
1164 ty::ReBound(..) | ty::ReErased => {
1165 ::rustc_span::macros::bug_impl(None,
format_args!("unexpected region for note_and_explain_region: {0:?}",
region), Location::caller());bug!("unexpected region for note_and_explain_region: {:?}", region);
1166 }
1167 };
1168
1169 emit_msg_span(err, prefix, description, span, suffix);
1170}
1171
1172fn explain_free_region<'tcx>(
1173 tcx: TyCtxt<'tcx>,
1174 err: &mut Diag<'_>,
1175 generic_param_scope: LocalDefId,
1176 prefix: &str,
1177 region: ty::Region<'tcx>,
1178 suffix: &str,
1179) {
1180 let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None);
1181
1182 label_msg_span(err, prefix, description, span, suffix);
1183}
1184
1185fn msg_span_from_named_region<'tcx>(
1186 tcx: TyCtxt<'tcx>,
1187 generic_param_scope: LocalDefId,
1188 region: ty::Region<'tcx>,
1189 alt_span: Option<Span>,
1190) -> (String, Option<Span>) {
1191 match region.kind() {
1192 ty::ReEarlyParam(br) => {
1193 let param_def_id = tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id;
1194 let span = tcx.def_span(param_def_id);
1195 let text = if br.is_named() {
1196 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the lifetime `{0}` as defined here",
br.name))
})format!("the lifetime `{}` as defined here", br.name)
1197 } else {
1198 "the anonymous lifetime as defined here".to_string()
1199 };
1200 (text, Some(span))
1201 }
1202 ty::ReLateParam(ref fr) => {
1203 if !fr.kind.is_named(tcx)
1204 && let Some((ty, _)) = find_anon_type(tcx, generic_param_scope, region)
1205 {
1206 ("the anonymous lifetime defined here".to_string(), Some(ty.span))
1207 } else {
1208 match fr.kind {
1209 ty::LateParamRegionKind::Named(param_def_id) => {
1210 let name = tcx.item_name(param_def_id);
1211 let span = tcx.def_span(param_def_id);
1212 let text = if name == kw::UnderscoreLifetime {
1213 "the anonymous lifetime as defined here".to_string()
1214 } else {
1215 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the lifetime `{0}` as defined here",
name))
})format!("the lifetime `{name}` as defined here")
1216 };
1217 (text, Some(span))
1218 }
1219 ty::LateParamRegionKind::Anon(_) => (
1220 "the anonymous lifetime as defined here".to_string(),
1221 Some(tcx.def_span(generic_param_scope)),
1222 ),
1223 _ => (
1224 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the lifetime `{0}` as defined here",
region))
})format!("the lifetime `{region}` as defined here"),
1225 Some(tcx.def_span(generic_param_scope)),
1226 ),
1227 }
1228 }
1229 }
1230 ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
1231 ty::RePlaceholder(ty::PlaceholderRegion {
1232 bound: ty::BoundRegion { kind: ty::BoundRegionKind::Named(def_id), .. },
1233 ..
1234 }) => (
1235 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the lifetime `{0}` as defined here",
tcx.item_name(def_id)))
})format!("the lifetime `{}` as defined here", tcx.item_name(def_id)),
1236 Some(tcx.def_span(def_id)),
1237 ),
1238 ty::RePlaceholder(ty::PlaceholderRegion {
1239 bound: ty::BoundRegion { kind: ty::BoundRegionKind::Anon, .. },
1240 ..
1241 }) => ("an anonymous lifetime".to_owned(), None),
1242 _ => ::rustc_span::macros::bug_impl(None, format_args!("{0:?}", region),
Location::caller())bug!("{:?}", region),
1243 }
1244}
1245
1246fn emit_msg_span(
1247 err: &mut Diag<'_>,
1248 prefix: &str,
1249 description: String,
1250 span: Option<Span>,
1251 suffix: &str,
1252) {
1253 let message = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}{2}", prefix, description,
suffix))
})format!("{prefix}{description}{suffix}");
1254
1255 if let Some(span) = span {
1256 err.span_note(span, message);
1257 } else {
1258 err.note(message);
1259 }
1260}
1261
1262fn label_msg_span(
1263 err: &mut Diag<'_>,
1264 prefix: &str,
1265 description: String,
1266 span: Option<Span>,
1267 suffix: &str,
1268) {
1269 let message = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}{2}", prefix, description,
suffix))
})format!("{prefix}{description}{suffix}");
1270
1271 if let Some(span) = span {
1272 err.span_label(span, message);
1273 } else {
1274 err.note(message);
1275 }
1276}
1277
1278{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("unexpected_hidden_region_diagnostic",
"rustc_trait_selection::error_reporting::infer::region",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
::tracing_core::__macro_support::Option::Some(1278u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("generic_param_scope")
}> =
::tracing::__macro_support::FieldName::new("generic_param_scope");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("span")
}> =
::tracing::__macro_support::FieldName::new("span");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("hidden_ty")
}> =
::tracing::__macro_support::FieldName::new("hidden_ty");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("hidden_region")
}> =
::tracing::__macro_support::FieldName::new("hidden_region");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("opaque_ty_key")
}> =
::tracing::__macro_support::FieldName::new("opaque_ty_key");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&generic_param_scope)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hidden_ty)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hidden_region)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&opaque_ty_key)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Diag<'a> = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = infcx.tcx;
let mut err =
infcx.dcx().create_err(diagnostics::OpaqueCapturesLifetime {
span,
opaque_ty: Ty::new_opaque(tcx, ty::IsRigid::No,
opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args),
opaque_ty_span: tcx.def_span(opaque_ty_key.def_id),
});
let mut highlight = RegionHighlightMode::default();
highlight.keep_regions = true;
let hidden_ty =
Highlighted {
highlight,
ns: Namespace::TypeNS,
tcx,
value: hidden_ty,
};
match hidden_region.kind() {
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
explain_free_region(tcx, &mut err, generic_param_scope,
&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("hidden type `{0}` captures ",
hidden_ty))
}), hidden_region, "");
if let Some(_) =
tcx.is_suitable_region(generic_param_scope, hidden_region) {
suggest_precise_capturing(tcx, opaque_ty_key.def_id,
hidden_region, &mut err);
}
}
ty::RePlaceholder(_) => {
explain_free_region(tcx, &mut err, generic_param_scope,
&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("hidden type `{0}` captures ",
hidden_ty))
}), hidden_region, "");
}
ty::ReError(_) => { err.downgrade_to_delayed_bug(); }
_ => {
note_and_explain_region(tcx, &mut err, generic_param_scope,
&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("hidden type `{0}` captures ",
hidden_ty))
}), hidden_region, "", None);
}
}
err
}
}
}#[instrument(level = "trace", skip(infcx))]
1279pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>(
1280 infcx: &'a InferCtxt<'tcx>,
1281 generic_param_scope: LocalDefId,
1282 span: Span,
1283 hidden_ty: Ty<'tcx>,
1284 hidden_region: ty::Region<'tcx>,
1285 opaque_ty_key: ty::OpaqueTypeKey<'tcx>,
1286) -> Diag<'a> {
1287 let tcx = infcx.tcx;
1288 let mut err = infcx.dcx().create_err(diagnostics::OpaqueCapturesLifetime {
1289 span,
1290 opaque_ty: Ty::new_opaque(
1291 tcx,
1292 ty::IsRigid::No,
1293 opaque_ty_key.def_id.to_def_id(),
1294 opaque_ty_key.args,
1295 ),
1296 opaque_ty_span: tcx.def_span(opaque_ty_key.def_id),
1297 });
1298 let mut highlight = RegionHighlightMode::default();
1299 highlight.keep_regions = true;
1300 let hidden_ty = Highlighted { highlight, ns: Namespace::TypeNS, tcx, value: hidden_ty };
1301
1302 match hidden_region.kind() {
1304 ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
1305 explain_free_region(
1314 tcx,
1315 &mut err,
1316 generic_param_scope,
1317 &format!("hidden type `{hidden_ty}` captures "),
1318 hidden_region,
1319 "",
1320 );
1321 if let Some(_) = tcx.is_suitable_region(generic_param_scope, hidden_region) {
1322 suggest_precise_capturing(tcx, opaque_ty_key.def_id, hidden_region, &mut err);
1323 }
1324 }
1325 ty::RePlaceholder(_) => {
1326 explain_free_region(
1327 tcx,
1328 &mut err,
1329 generic_param_scope,
1330 &format!("hidden type `{}` captures ", hidden_ty),
1331 hidden_region,
1332 "",
1333 );
1334 }
1335 ty::ReError(_) => {
1336 err.downgrade_to_delayed_bug();
1337 }
1338 _ => {
1339 note_and_explain_region(
1355 tcx,
1356 &mut err,
1357 generic_param_scope,
1358 &format!("hidden type `{hidden_ty}` captures "),
1359 hidden_region,
1360 "",
1361 None,
1362 );
1363 }
1364 }
1365
1366 err
1367}
1368
1369fn suggest_precise_capturing<'tcx>(
1370 tcx: TyCtxt<'tcx>,
1371 opaque_def_id: LocalDefId,
1372 captured_lifetime: ty::Region<'tcx>,
1373 diag: &mut Diag<'_>,
1374) {
1375 let hir::OpaqueTy { bounds, origin, .. } =
1376 tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
1377
1378 let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
1379 return;
1380 };
1381
1382 let new_lifetime = Symbol::intern(&captured_lifetime.to_string());
1383
1384 if let Some((args, span)) = bounds.iter().find_map(|bound| match bound {
1385 hir::GenericBound::Use(args, span) => Some((args, span)),
1386 _ => None,
1387 }) {
1388 if args.iter().any(|arg| {
1392 #[allow(non_exhaustive_omitted_patterns)] match arg {
hir::PreciseCapturingArg::Lifetime(lt) if lt.ident.name == new_lifetime =>
true,
_ => false,
}matches!(arg, hir::PreciseCapturingArg::Lifetime(lt) if lt.ident.name == new_lifetime)
1393 }) {
1394 return;
1395 }
1396
1397 let last_lifetime_span = args.iter().rev().find_map(|arg| match arg {
1398 hir::PreciseCapturingArg::Lifetime(lt) => Some(lt.ident.span),
1399 _ => None,
1400 });
1401
1402 let first_param_span = args.iter().find_map(|arg| match arg {
1403 hir::PreciseCapturingArg::Param(p) => Some(p.ident.span),
1404 _ => None,
1405 });
1406
1407 let (span, pre, post) = if let Some(last_lifetime_span) = last_lifetime_span {
1408 (last_lifetime_span.shrink_to_hi(), ", ", "")
1409 } else if let Some(first_param_span) = first_param_span {
1410 (first_param_span.shrink_to_lo(), "", ", ")
1411 } else {
1412 (span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(), "", "")
1416 };
1417
1418 diag.subdiagnostic(diagnostics::AddPreciseCapturing::Existing {
1419 span,
1420 new_lifetime,
1421 pre,
1422 post,
1423 });
1424 } else {
1425 let mut captured_lifetimes = FxIndexSet::default();
1426 let mut captured_non_lifetimes = FxIndexSet::default();
1427
1428 let variances = tcx.variances_of(opaque_def_id);
1429 let mut generics = tcx.generics_of(opaque_def_id);
1430 let mut synthetics = ::alloc::vec::Vec::new()vec![];
1431 loop {
1432 for param in &generics.own_params {
1433 if variances[param.index as usize] == ty::Bivariant {
1434 continue;
1435 }
1436
1437 match param.kind {
1438 ty::GenericParamDefKind::Lifetime => {
1439 captured_lifetimes.insert(param.name);
1440 }
1441 ty::GenericParamDefKind::Type { synthetic: true, .. } => {
1442 synthetics.push((tcx.def_span(param.def_id), param.name));
1443 }
1444 ty::GenericParamDefKind::Type { .. }
1445 | ty::GenericParamDefKind::Const { .. } => {
1446 captured_non_lifetimes.insert(param.name);
1447 }
1448 }
1449 }
1450
1451 if let Some(parent) = generics.parent {
1452 generics = tcx.generics_of(parent);
1453 } else {
1454 break;
1455 }
1456 }
1457
1458 if !captured_lifetimes.insert(new_lifetime) {
1459 return;
1461 }
1462
1463 if synthetics.is_empty() {
1464 let concatenated_bounds = captured_lifetimes
1465 .into_iter()
1466 .chain(captured_non_lifetimes)
1467 .map(|sym| sym.to_string())
1468 .collect::<Vec<_>>()
1469 .join(", ");
1470
1471 diag.subdiagnostic(diagnostics::AddPreciseCapturing::New {
1472 span: tcx.def_span(opaque_def_id).shrink_to_hi(),
1473 new_lifetime,
1474 concatenated_bounds,
1475 });
1476 } else {
1477 let mut next_fresh_param = || {
1478 ['T', 'U', 'V', 'W', 'X', 'Y', 'A', 'B', 'C']
1479 .into_iter()
1480 .map(sym::character)
1481 .chain((0..).map(|i| Symbol::intern(&::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("T{0}", i)) })format!("T{i}"))))
1482 .find(|s| captured_non_lifetimes.insert(*s))
1483 .unwrap()
1484 };
1485
1486 let mut new_params = String::new();
1487 let mut suggs = ::alloc::vec::Vec::new()vec![];
1488 let mut apit_spans = ::alloc::vec::Vec::new()vec![];
1489
1490 for (i, (span, name)) in synthetics.into_iter().enumerate() {
1491 apit_spans.push(span);
1492
1493 let fresh_param = next_fresh_param();
1494
1495 suggs.push((span, fresh_param.to_string()));
1497
1498 if i > 0 {
1506 new_params += ", ";
1507 }
1508 let name_as_bounds = name.as_str().trim_start_matches("impl").trim_start();
1509 new_params += fresh_param.as_str();
1510 new_params += ": ";
1511 new_params += name_as_bounds;
1512 }
1513
1514 let Some(generics) = tcx.hir_get_generics(fn_def_id) else {
1515 return;
1517 };
1518
1519 suggs.push(if let Some(params_span) = generics.span_for_param_suggestion() {
1521 (params_span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(", {0}", new_params))
})format!(", {new_params}"))
1522 } else {
1523 (generics.span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{0}>", new_params))
})format!("<{new_params}>"))
1524 });
1525
1526 let concatenated_bounds = captured_lifetimes
1527 .into_iter()
1528 .chain(captured_non_lifetimes)
1529 .map(|sym| sym.to_string())
1530 .collect::<Vec<_>>()
1531 .join(", ");
1532
1533 suggs.push((
1534 tcx.def_span(opaque_def_id).shrink_to_hi(),
1535 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" + use<{0}>", concatenated_bounds))
})format!(" + use<{concatenated_bounds}>"),
1536 ));
1537
1538 diag.subdiagnostic(diagnostics::AddPreciseCapturingAndParams {
1539 suggs,
1540 new_lifetime,
1541 apit_spans,
1542 });
1543 }
1544 }
1545}