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