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