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