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