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