Skip to main content

rustc_trait_selection/error_reporting/infer/
region.rs

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        // try to pre-process the errors, which will group some of them
49        // together into a `ProcessedErrors` group:
50        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                    // These errors could indicate all manner of different
65                    // problems with many different solutions. Rather
66                    // than generate a "one size fits all" error, what we
67                    // attempt to do is go through a number of specific
68                    // scenarios and try to find the best way to present
69                    // the error. If all of these fails, we fall back to a rather
70                    // general bit of code that displays the error information
71                    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                        // Make a dummy value for the "sub region" --
137                        // this is the initial value of the
138                        // placeholder. In practice, we expect more
139                        // tailored errors that don't really use this
140                        // value.
141                        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    // This method goes through all the errors and try to group certain types
170    // of error together, for the purpose of suggesting explicit lifetime
171    // parameters to the user. This is done so that we can have a more
172    // complete view of what lifetimes should be the same.
173    // If the return value is an empty vector, it means that processing
174    // failed (so the return value of this method should not be used).
175    //
176    // The method also attempts to weed out messages that seem like
177    // duplicates that will be unhelpful to the end-user. But
178    // obviously it never weeds out ALL errors.
179    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        // We want to avoid reporting generic-bound failures if we can
186        // avoid it: these have a very high rate of being unhelpful in
187        // practice. This is because they are basically secondary
188        // checks that test the state of the region graph after the
189        // rest of inference is done, and the other kinds of errors
190        // indicate that the region constraint graph is internally
191        // inconsistent, so these test results are likely to be
192        // meaningless.
193        //
194        // Therefore, we filter them out of the list unless they are
195        // the only thing in the list.
196
197        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        // sort the errors by span, for better error message stability.
212        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                            // Point at explicit `'static` bound on the trait (`trait T: 'static`).
453                            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                // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
505                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                // Don't mention the item name if it's an RPITIT, since that'll just confuse
524                // folks.
525                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        // FIXME(compiler-errors): Right now this is only being used for region
577        // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
578        // but right now it's not really very smart when it comes to implicit `Sized`
579        // predicates and bounds on the trait itself.
580
581        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            // Replace the explicit self type with `Self` for better suggestion rendering
589            .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        // I can't think how to do better than this right now. -nikomatsakis
632        {
    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                // Hack to get around the borrow checker because trace.cause has an `Rc`.
642                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            // type_param_sugg_span is (span, has_bounds, needs_parentheses)
771            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                    // Get the `hir::Param` to verify whether it already has any bounds.
778                    // We do this to avoid suggesting code that ends up as `T: 'a'b`,
779                    // instead we suggest `T: 'a + 'b` in that case.
780                    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                        // If `param` corresponds to `Self`, no usable suggestion span.
786                        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                // The lifetime found in the `impl` is longer than the one on the RPITIT.
853                // Do not suggest `<Type as Trait>::{opaque}: 'static`.
854            } 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, // Issue #41966
868                );
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            // Explicitly look for `-> Box<dyn Trait>` to point at it as the *likely* source of
901            // the `'static` lifetime requirement.
902            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            // consider late-bound lifetimes ...
949            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        // FIXME(#125431): `ReVar` shouldn't reach here.
1138        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    // Explain the region we are capturing.
1271    match hidden_region.kind() {
1272        ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
1273            // Assuming regionck succeeded (*), we ought to always be
1274            // capturing *some* region from the fn header, and hence it
1275            // ought to be free. So under normal circumstances, we will go
1276            // down this path which gives a decent human readable
1277            // explanation.
1278            //
1279            // (*) if not, the `tainted_by_errors` field would be set to
1280            // `Some(ErrorGuaranteed)` in any case, so we wouldn't be here at all.
1281            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            // Ugh. This is a painful case: the hidden region is not one
1308            // that we can easily summarize or explain. This can happen
1309            // in a case like
1310            // `tests/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`:
1311            //
1312            // ```
1313            // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> {
1314            //   if condition() { a } else { b }
1315            // }
1316            // ```
1317            //
1318            // Here the captured lifetime is the intersection of `'a` and
1319            // `'b`, which we can't quite express.
1320
1321            // We can at least report a really cryptic error for now.
1322            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            // If we have no args, then have `use<>` and need to fall back to using
1372            // span math. This sucks, but should be reliable due to the construction
1373            // of the `use<>` span.
1374            (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            // Uh, strange. This lifetime appears to already be captured...
1414            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                // Suggest renaming.
1450                suggs.push((span, fresh_param.to_string()));
1451
1452                // Super jank. Turn `impl Trait` into `T: Trait`.
1453                //
1454                // This currently involves stripping the `impl` from the name of
1455                // the parameter, since APITs are always named after how they are
1456                // rendered in the AST. This sucks! But to recreate the bound list
1457                // from the APIT itself would be miserable, so we're stuck with
1458                // this for now!
1459                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                // This shouldn't happen, but don't ICE.
1470                return;
1471            };
1472
1473            // Add generics or concatenate to the end of the list.
1474            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}