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, Namespace};
8use rustc_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::intravisit::Visitor;
10use rustc_hir::{self as hir, ParamName};
11use rustc_middle::traits::ObligationCauseCode;
12use rustc_middle::ty::error::TypeError;
13use rustc_middle::ty::print::RegionHighlightMode;
14use rustc_middle::ty::{
15    self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _, Upcast as _,
16};
17use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol, bug, kw, sym};
18use tracing::{debug, instrument};
19
20use super::ObligationCauseAsDiagArg;
21use super::nice_region_error::find_anon_type;
22use crate::diagnostics::{
23    self, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
24    RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, note_and_explain,
25};
26use crate::error_reporting::TypeErrCtxt;
27use crate::error_reporting::infer::ObligationCauseExt;
28use crate::error_reporting::infer::nice_region_error::placeholder_error::Highlighted;
29use crate::infer::region_constraints::GenericKind;
30use crate::infer::{
31    BoundRegionConversionTime, InferCtxt, RegionResolutionError, RegionVariableOrigin,
32    SubregionOrigin,
33};
34
35impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
36    pub fn report_region_errors(
37        &self,
38        generic_param_scope: LocalDefId,
39        errors: &[RegionResolutionError<'tcx>],
40    ) -> ErrorGuaranteed {
41        if !!errors.is_empty() {
    ::core::panicking::panic("assertion failed: !errors.is_empty()")
};assert!(!errors.is_empty());
42
43        if let Some(guaranteed) = self.infcx.tainted_by_errors() {
44            return guaranteed;
45        }
46
47        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:47",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(47u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_region_errors(): {0} errors to start",
                                                    errors.len()) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_region_errors(): {} errors to start", errors.len());
48
49        // try to pre-process the errors, which will group some of them
50        // together into a `ProcessedErrors` group:
51        let errors = self.process_errors(errors);
52
53        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:53",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(53u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_region_errors: {0} errors after preprocessing",
                                                    errors.len()) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_region_errors: {} errors after preprocessing", errors.len());
54
55        let mut guar = None;
56        for error in errors {
57            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:57",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(57u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_region_errors: error = {0:?}",
                                                    error) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_region_errors: error = {:?}", error);
58
59            let e = if let Some(guar) =
60                self.try_report_nice_region_error(generic_param_scope, &error)
61            {
62                guar
63            } else {
64                match error.clone() {
65                    // These errors could indicate all manner of different
66                    // problems with many different solutions. Rather
67                    // than generate a "one size fits all" error, what we
68                    // attempt to do is go through a number of specific
69                    // scenarios and try to find the best way to present
70                    // the error. If all of these fails, we fall back to a rather
71                    // general bit of code that displays the error information
72                    RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
73                        if sub.is_placeholder() || sup.is_placeholder() {
74                            self.report_placeholder_failure(generic_param_scope, origin, sub, sup)
75                                .emit_err()
76                        } else {
77                            self.report_concrete_failure(generic_param_scope, origin, sub, sup)
78                                .emit_err()
79                        }
80                    }
81
82                    RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self
83                        .report_generic_bound_failure(
84                            generic_param_scope,
85                            origin.span(),
86                            Some(origin),
87                            param_ty,
88                            sub,
89                        ),
90
91                    RegionResolutionError::SubSupConflict(
92                        _,
93                        var_origin,
94                        sub_origin,
95                        sub_r,
96                        sup_origin,
97                        sup_r,
98                        _,
99                    ) => {
100                        if sub_r.is_placeholder() {
101                            self.report_placeholder_failure(
102                                generic_param_scope,
103                                sub_origin,
104                                sub_r,
105                                sup_r,
106                            )
107                            .emit_err()
108                        } else if sup_r.is_placeholder() {
109                            self.report_placeholder_failure(
110                                generic_param_scope,
111                                sup_origin,
112                                sub_r,
113                                sup_r,
114                            )
115                            .emit_err()
116                        } else {
117                            self.report_sub_sup_conflict(
118                                generic_param_scope,
119                                var_origin,
120                                sub_origin,
121                                sub_r,
122                                sup_origin,
123                                sup_r,
124                            )
125                        }
126                    }
127
128                    RegionResolutionError::UpperBoundUniverseConflict(
129                        _,
130                        _,
131                        _,
132                        sup_origin,
133                        sup_r,
134                    ) => {
135                        if !sup_r.is_placeholder() {
    ::core::panicking::panic("assertion failed: sup_r.is_placeholder()")
};assert!(sup_r.is_placeholder());
136
137                        // Make a dummy value for the "sub region" --
138                        // this is the initial value of the
139                        // placeholder. In practice, we expect more
140                        // tailored errors that don't really use this
141                        // value.
142                        let sub_r = self.tcx.lifetimes.re_erased;
143
144                        self.report_placeholder_failure(
145                            generic_param_scope,
146                            sup_origin,
147                            sub_r,
148                            sup_r,
149                        )
150                        .emit_err()
151                    }
152
153                    RegionResolutionError::CannotNormalize(clause, origin) => {
154                        let clause: ty::Clause<'tcx> =
155                            clause.map_bound(ty::ClauseKind::TypeOutlives).upcast(self.tcx);
156                        self.tcx
157                            .dcx()
158                            .struct_span_err(origin.span(), ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("cannot normalize `{0}`", clause))
    })format!("cannot normalize `{clause}`"))
159                            .emit_err()
160                    }
161                }
162            };
163
164            guar = Some(e)
165        }
166
167        guar.unwrap()
168    }
169
170    // This method goes through all the errors and try to group certain types
171    // of error together, for the purpose of suggesting explicit lifetime
172    // parameters to the user. This is done so that we can have a more
173    // complete view of what lifetimes should be the same.
174    // If the return value is an empty vector, it means that processing
175    // failed (so the return value of this method should not be used).
176    //
177    // The method also attempts to weed out messages that seem like
178    // duplicates that will be unhelpful to the end-user. But
179    // obviously it never weeds out ALL errors.
180    fn process_errors(
181        &self,
182        errors: &[RegionResolutionError<'tcx>],
183    ) -> Vec<RegionResolutionError<'tcx>> {
184        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:184",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(184u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("process_errors()")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("process_errors()");
185
186        // We want to avoid reporting generic-bound failures if we can
187        // avoid it: these have a very high rate of being unhelpful in
188        // practice. This is because they are basically secondary
189        // checks that test the state of the region graph after the
190        // rest of inference is done, and the other kinds of errors
191        // indicate that the region constraint graph is internally
192        // inconsistent, so these test results are likely to be
193        // meaningless.
194        //
195        // Therefore, we filter them out of the list unless they are
196        // the only thing in the list.
197
198        let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e {
199            RegionResolutionError::GenericBoundFailure(..) => true,
200            RegionResolutionError::ConcreteFailure(..)
201            | RegionResolutionError::SubSupConflict(..)
202            | RegionResolutionError::UpperBoundUniverseConflict(..)
203            | RegionResolutionError::CannotNormalize(..) => false,
204        };
205
206        let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
207            errors.to_owned()
208        } else {
209            errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
210        };
211
212        // sort the errors by span, for better error message stability.
213        errors.sort_by_key(|u| {
214            match *u {
215                RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(),
216                RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(),
217                RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(),
218                RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => {
219                    rvo.span()
220                }
221                RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(),
222            }
223            .lo_hi()
224        });
225        errors
226    }
227
228    pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
229        match *origin {
230            SubregionOrigin::Subtype(ref trace) => RegionOriginNote::WithRequirement {
231                span: trace.cause.span,
232                requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
233                expected_found: self.values_str(trace.values, &trace.cause, err.long_ty_path()),
234            }
235            .add_to_diag(err),
236            SubregionOrigin::Reborrow(span) => RegionOriginNote::Plain {
237                span,
238                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"),
239            }
240            .add_to_diag(err),
241            SubregionOrigin::RelateObjectBound(span) => {
242                RegionOriginNote::Plain {
243                    span,
244                    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"),
245                }
246                .add_to_diag(err);
247            }
248            SubregionOrigin::ReferenceOutlivesReferent(ty, span) => {
249                RegionOriginNote::WithName {
250                    span,
251                    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"),
252                    name: &self.ty_to_string(ty),
253                    continues: false,
254                }
255                .add_to_diag(err);
256            }
257            SubregionOrigin::RelateParamBound(span, ty, opt_span) => {
258                RegionOriginNote::WithName {
259                    span,
260                    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!(
261                        "...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
262                            [true] ...
263                            *[false] {\"\"}
264                        }"
265                    ),
266                    name: &self.ty_to_string(ty),
267                    continues: opt_span.is_some(),
268                }
269                .add_to_diag(err);
270                if let Some(span) = opt_span {
271                    RegionOriginNote::Plain {
272                        span,
273                        msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...that is required by this bound"))msg!("...that is required by this bound"),
274                    }
275                    .add_to_diag(err);
276                }
277            }
278            SubregionOrigin::RelateRegionParamBound(span, _) => {
279                RegionOriginNote::Plain {
280                    span,
281                    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"),
282                }
283                .add_to_diag(err);
284            }
285            SubregionOrigin::CompareImplItemObligation { span, .. } => {
286                RegionOriginNote::Plain {
287                    span,
288                    msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that the definition in impl matches the definition from the trait"))msg!(
289                        "...so that the definition in impl matches the definition from the trait"
290                    ),
291                }
292                .add_to_diag(err);
293            }
294            SubregionOrigin::CheckAssociatedTypeBounds { ref parent, .. } => {
295                self.note_region_origin(err, parent);
296            }
297            SubregionOrigin::AscribeUserTypeProvePredicate(span, _) => {
298                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") }
299                    .add_to_diag(err);
300            }
301            SubregionOrigin::SolverRegionConstraint(span) => {
302                RegionOriginNote::Plain {
303                    span,
304                    msg: rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("...so that a higher-ranked lifetime bound can be satisfied"))msg!("...so that a higher-ranked lifetime bound can be satisfied"),
305                }
306                .add_to_diag(err);
307            }
308        }
309    }
310
311    pub(super) fn report_concrete_failure(
312        &self,
313        generic_param_scope: LocalDefId,
314        origin: SubregionOrigin<'tcx>,
315        sub: Region<'tcx>,
316        sup: Region<'tcx>,
317    ) -> Diag<'a> {
318        let mut err = match origin {
319            SubregionOrigin::Subtype(trace) => {
320                let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
321                let mut err = self.report_and_explain_type_error(
322                    *trace,
323                    self.tcx.param_env(generic_param_scope),
324                    terr,
325                );
326                match (sub.kind(), sup.kind()) {
327                    (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
328                    (ty::RePlaceholder(_), _) => {
329                        note_and_explain_region(
330                            self.tcx,
331                            &mut err,
332                            generic_param_scope,
333                            "",
334                            sup,
335                            " doesn't meet the lifetime requirements",
336                            None,
337                        );
338                    }
339                    (_, ty::RePlaceholder(_)) => {
340                        note_and_explain_region(
341                            self.tcx,
342                            &mut err,
343                            generic_param_scope,
344                            "the required lifetime does not necessarily outlive ",
345                            sub,
346                            "",
347                            None,
348                        );
349                    }
350                    _ => {
351                        note_and_explain_region(
352                            self.tcx,
353                            &mut err,
354                            generic_param_scope,
355                            "",
356                            sup,
357                            "...",
358                            None,
359                        );
360                        note_and_explain_region(
361                            self.tcx,
362                            &mut err,
363                            generic_param_scope,
364                            "...does not necessarily outlive ",
365                            sub,
366                            "",
367                            None,
368                        );
369                    }
370                }
371                err
372            }
373            SubregionOrigin::Reborrow(span) => {
374                let reference_valid = note_and_explain::RegionExplanation::new(
375                    self.tcx,
376                    generic_param_scope,
377                    sub,
378                    None,
379                    note_and_explain::PrefixKind::RefValidFor,
380                    note_and_explain::SuffixKind::Continues,
381                );
382                let content_valid = note_and_explain::RegionExplanation::new(
383                    self.tcx,
384                    generic_param_scope,
385                    sup,
386                    None,
387                    note_and_explain::PrefixKind::ContentValidFor,
388                    note_and_explain::SuffixKind::Empty,
389                );
390                self.dcx().create_err(OutlivesContent {
391                    span,
392                    notes: reference_valid.into_iter().chain(content_valid).collect(),
393                })
394            }
395            SubregionOrigin::RelateObjectBound(span) => {
396                let object_valid = note_and_explain::RegionExplanation::new(
397                    self.tcx,
398                    generic_param_scope,
399                    sub,
400                    None,
401                    note_and_explain::PrefixKind::TypeObjValidFor,
402                    note_and_explain::SuffixKind::Empty,
403                );
404                let pointer_valid = note_and_explain::RegionExplanation::new(
405                    self.tcx,
406                    generic_param_scope,
407                    sup,
408                    None,
409                    note_and_explain::PrefixKind::SourcePointerValidFor,
410                    note_and_explain::SuffixKind::Empty,
411                );
412                self.dcx().create_err(OutlivesBound {
413                    span,
414                    notes: object_valid.into_iter().chain(pointer_valid).collect(),
415                })
416            }
417            SubregionOrigin::RelateParamBound(span, ty, opt_span) => {
418                let prefix = match sub.kind() {
419                    ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
420                    _ => note_and_explain::PrefixKind::TypeOutlive,
421                };
422                let suffix = if opt_span.is_some() {
423                    note_and_explain::SuffixKind::ReqByBinding
424                } else {
425                    note_and_explain::SuffixKind::Empty
426                };
427                let note = note_and_explain::RegionExplanation::new(
428                    self.tcx,
429                    generic_param_scope,
430                    sub,
431                    opt_span,
432                    prefix,
433                    suffix,
434                );
435                self.dcx().create_err(FulfillReqLifetime {
436                    span,
437                    ty: self.deeply_resolve_ignoring_regions(ty),
438                    note,
439                })
440            }
441            SubregionOrigin::RelateRegionParamBound(span, ty) => {
442                let param_instantiated = note_and_explain::RegionExplanation::new(
443                    self.tcx,
444                    generic_param_scope,
445                    sup,
446                    None,
447                    note_and_explain::PrefixKind::LfParamInstantiatedWith,
448                    note_and_explain::SuffixKind::Empty,
449                );
450                let mut alt_span = None;
451                if let Some(ty) = ty
452                    && sub.is_static()
453                    && let ty::Dynamic(preds, _) = ty.kind()
454                    && let Some(def_id) = preds.principal_def_id()
455                {
456                    for (clause, span) in
457                        self.tcx.clauses_of(def_id).instantiate_identity(self.tcx).into_iter()
458                    {
459                        if let ty::ClauseKind::TypeOutlives(ty::OutlivesClause(a, b)) =
460                            clause.kind().skip_binder()
461                            && let ty::Param(param) = a.kind()
462                            && param.name == kw::SelfUpper
463                            && b.is_static()
464                        {
465                            // Point at explicit `'static` bound on the trait (`trait T: 'static`).
466                            alt_span = Some(span);
467                        }
468                    }
469                }
470                let param_must_outlive = note_and_explain::RegionExplanation::new(
471                    self.tcx,
472                    generic_param_scope,
473                    sub,
474                    alt_span,
475                    note_and_explain::PrefixKind::LfParamMustOutlive,
476                    note_and_explain::SuffixKind::Empty,
477                );
478                self.dcx().create_err(LfBoundNotSatisfied {
479                    span,
480                    notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
481                })
482            }
483            SubregionOrigin::ReferenceOutlivesReferent(ty, span) => {
484                let pointer_valid = note_and_explain::RegionExplanation::new(
485                    self.tcx,
486                    generic_param_scope,
487                    sub,
488                    None,
489                    note_and_explain::PrefixKind::PointerValidFor,
490                    note_and_explain::SuffixKind::Empty,
491                );
492                let data_valid = note_and_explain::RegionExplanation::new(
493                    self.tcx,
494                    generic_param_scope,
495                    sup,
496                    None,
497                    note_and_explain::PrefixKind::DataValidFor,
498                    note_and_explain::SuffixKind::Empty,
499                );
500                self.dcx().create_err(RefLongerThanData {
501                    span,
502                    ty: self.deeply_resolve_ignoring_regions(ty),
503                    notes: pointer_valid.into_iter().chain(data_valid).collect(),
504                })
505            }
506            SubregionOrigin::CompareImplItemObligation {
507                span,
508                impl_item_def_id,
509                trait_item_def_id,
510            } => {
511                let mut err = self.report_extra_impl_obligation(
512                    span,
513                    impl_item_def_id,
514                    trait_item_def_id,
515                    &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}: {1}`", sup, sub))
    })format!("`{sup}: {sub}`"),
516                );
517                // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
518                if let Some(generics) = self.tcx.hir_get_generics(impl_item_def_id)
519                    && generics.where_clause_span.contains(span)
520                {
521                    self.suggest_copy_trait_method_bounds(
522                        trait_item_def_id,
523                        impl_item_def_id,
524                        &mut err,
525                    );
526                }
527                err
528            }
529            SubregionOrigin::CheckAssociatedTypeBounds {
530                impl_item_def_id,
531                trait_item_def_id,
532                parent,
533            } => {
534                let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
535
536                // Don't mention the item name if it's an RPITIT, since that'll just confuse
537                // folks.
538                if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
539                    let trait_item_span = self.tcx.def_span(trait_item_def_id);
540                    let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
541                    err.span_label(
542                        trait_item_span,
543                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("definition of `{0}` from trait",
                item_name))
    })format!("definition of `{item_name}` from trait"),
544                    );
545                }
546
547                self.suggest_copy_trait_method_bounds(
548                    trait_item_def_id,
549                    impl_item_def_id,
550                    &mut err,
551                );
552                err
553            }
554            SubregionOrigin::AscribeUserTypeProvePredicate(span, _) => {
555                let instantiated = note_and_explain::RegionExplanation::new(
556                    self.tcx,
557                    generic_param_scope,
558                    sup,
559                    None,
560                    note_and_explain::PrefixKind::LfInstantiatedWith,
561                    note_and_explain::SuffixKind::Empty,
562                );
563                let must_outlive = note_and_explain::RegionExplanation::new(
564                    self.tcx,
565                    generic_param_scope,
566                    sub,
567                    None,
568                    note_and_explain::PrefixKind::LfMustOutlive,
569                    note_and_explain::SuffixKind::Empty,
570                );
571                self.dcx().create_err(LfBoundNotSatisfied {
572                    span,
573                    notes: instantiated.into_iter().chain(must_outlive).collect(),
574                })
575            }
576            SubregionOrigin::SolverRegionConstraint(span) => self
577                .dcx()
578                .struct_span_err(span, "higher-ranked lifetime bound could not be satisfied"),
579        };
580        if sub.is_error() || sup.is_error() {
581            err.downgrade_to_delayed_bug();
582        }
583        err
584    }
585
586    pub fn suggest_copy_trait_method_bounds(
587        &self,
588        trait_item_def_id: DefId,
589        impl_item_def_id: LocalDefId,
590        err: &mut Diag<'_>,
591    ) {
592        // FIXME(compiler-errors): Right now this is only being used for region
593        // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
594        // but right now it's not really very smart when it comes to implicit `Sized`
595        // predicates and bounds on the trait itself.
596
597        let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(impl_item_def_id.to_def_id()) else {
598            return;
599        };
600        let trait_ref = self.tcx.impl_trait_ref(impl_def_id);
601        let trait_args = trait_ref
602            .instantiate_identity()
603            .skip_norm_wip()
604            // Replace the explicit self type with `Self` for better suggestion rendering
605            .with_replaced_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
606            .args;
607        let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
608            .rebase_onto(self.tcx, impl_def_id, trait_args);
609
610        let Ok(trait_predicates) = self
611            .tcx
612            .explicit_clauses_of(trait_item_def_id)
613            .instantiate_own(self.tcx, trait_item_args)
614            .map(|(clause, _)| {
615                let clause = clause.skip_norm_wip();
616                if clause.is_suggestable(self.tcx, false) {
617                    Ok(clause.to_string())
618                } else {
619                    Err(())
620                }
621            })
622            .collect::<Result<Vec<_>, ()>>()
623        else {
624            return;
625        };
626
627        let Some(generics) = self.tcx.hir_get_generics(impl_item_def_id) else {
628            return;
629        };
630
631        let suggestion = if trait_predicates.is_empty() {
632            WhereClauseSuggestions::Remove { span: generics.where_clause_span }
633        } else {
634            let space = if generics.where_clause_span.is_empty() { " " } else { "" };
635            WhereClauseSuggestions::CopyPredicates {
636                span: generics.where_clause_span,
637                space,
638                trait_predicates: trait_predicates.join(", "),
639            }
640        };
641        err.subdiagnostic(suggestion);
642    }
643
644    pub(super) fn report_placeholder_failure(
645        &self,
646        generic_param_scope: LocalDefId,
647        placeholder_origin: SubregionOrigin<'tcx>,
648        sub: Region<'tcx>,
649        sup: Region<'tcx>,
650    ) -> Diag<'a> {
651        // I can't think how to do better than this right now. -nikomatsakis
652        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:652",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(652u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("placeholder_origin")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("placeholder_origin");
                                            NAME.as_str()
                                        },
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("sub")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("sub");
                                            NAME.as_str()
                                        },
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("sup")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("sup");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_placeholder_failure")
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&placeholder_origin)
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sub)
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sup)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
653        match placeholder_origin {
654            SubregionOrigin::Subtype(ref trace)
655                if #[allow(non_exhaustive_omitted_patterns)] match &trace.cause.code().peel_derives()
    {
    ObligationCauseCode::WhereClause(..) |
        ObligationCauseCode::WhereClauseInExpr(..) => true,
    _ => false,
}matches!(
656                    &trace.cause.code().peel_derives(),
657                    ObligationCauseCode::WhereClause(..)
658                        | ObligationCauseCode::WhereClauseInExpr(..)
659                ) =>
660            {
661                // Hack to get around the borrow checker because trace.cause has an `Rc`.
662                if let ObligationCauseCode::WhereClause(_, span)
663                | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
664                    &trace.cause.code().peel_derives()
665                {
666                    let span = *span;
667                    let mut err = self.report_concrete_failure(
668                        generic_param_scope,
669                        placeholder_origin,
670                        sub,
671                        sup,
672                    );
673                    if !span.is_dummy() {
674                        err =
675                            err.with_span_note(span, "the lifetime requirement is introduced here");
676                    }
677                    err
678                } else {
679                    {
    ::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!(
680                        "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
681                    )
682                }
683            }
684            SubregionOrigin::Subtype(trace) => {
685                let terr = TypeError::RegionsPlaceholderMismatch;
686                return self.report_and_explain_type_error(
687                    *trace,
688                    self.tcx.param_env(generic_param_scope),
689                    terr,
690                );
691            }
692            _ => {
693                return self.report_concrete_failure(
694                    generic_param_scope,
695                    placeholder_origin,
696                    sub,
697                    sup,
698                );
699            }
700        }
701    }
702
703    pub fn report_generic_bound_failure(
704        &self,
705        generic_param_scope: LocalDefId,
706        span: Span,
707        origin: Option<SubregionOrigin<'tcx>>,
708        bound_kind: GenericKind<'tcx>,
709        sub: Region<'tcx>,
710    ) -> ErrorGuaranteed {
711        self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub)
712            .emit_err()
713    }
714
715    pub fn construct_generic_bound_failure(
716        &self,
717        generic_param_scope: LocalDefId,
718        span: Span,
719        origin: Option<SubregionOrigin<'tcx>>,
720        bound_kind: GenericKind<'tcx>,
721        sub: Region<'tcx>,
722    ) -> Diag<'a> {
723        if let Some(SubregionOrigin::CompareImplItemObligation {
724            span,
725            impl_item_def_id,
726            trait_item_def_id,
727        }) = origin
728        {
729            return self.report_extra_impl_obligation(
730                span,
731                impl_item_def_id,
732                trait_item_def_id,
733                &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}: {1}`", bound_kind, sub))
    })format!("`{bound_kind}: {sub}`"),
734            );
735        }
736
737        let labeled_user_string = match bound_kind {
738            GenericKind::Param(_) => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the parameter type `{0}`",
                bound_kind))
    })format!("the parameter type `{bound_kind}`"),
739            GenericKind::Placeholder(_) => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the placeholder type `{0}`",
                bound_kind))
    })format!("the placeholder type `{bound_kind}`"),
740            GenericKind::Alias(p) => match p.kind {
741                ty::Projection { .. } | ty::Inherent { .. } => {
742                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the associated type `{0}`",
                bound_kind))
    })format!("the associated type `{bound_kind}`")
743                }
744                ty::Free { .. } => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the type alias `{0}`", bound_kind))
    })format!("the type alias `{bound_kind}`"),
745                ty::Opaque { .. } => ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the opaque type `{0}`",
                bound_kind))
    })format!("the opaque type `{bound_kind}`"),
746            },
747        };
748
749        let mut err = self
750            .tcx
751            .dcx()
752            .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"));
753        err.code(match sub.kind() {
754            ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.is_named(self.tcx) => E0309,
755            ty::ReStatic => E0310,
756            _ => E0311,
757        });
758
759        '_explain: {
760            let (description, span) = match sub.kind() {
761                ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
762                    msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span))
763                }
764                _ => (::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("lifetime `{0}`", sub))
    })format!("lifetime `{sub}`"), Some(span)),
765            };
766            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 ");
767            label_msg_span(&mut err, &prefix, description, span, "...");
768            if let Some(origin) = origin {
769                self.note_region_origin(&mut err, &origin);
770            }
771        }
772
773        'suggestion: {
774            let msg = "consider adding an explicit lifetime bound";
775
776            if (bound_kind, sub).has_infer_regions()
777                || (bound_kind, sub).has_placeholders()
778                || !bound_kind.is_suggestable(self.tcx, false)
779            {
780                let lt_name = sub.get_name_or_anon(self.tcx).to_string();
781                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}`..."));
782                break 'suggestion;
783            }
784
785            let mut generic_param_scope = generic_param_scope;
786            while self.tcx.def_kind(generic_param_scope) == DefKind::OpaqueTy {
787                generic_param_scope = self.tcx.local_parent(generic_param_scope);
788            }
789
790            // type_param_sugg_span is (span, has_bounds, needs_parentheses)
791            let (type_scope, type_param_sugg_span) = match bound_kind {
792                GenericKind::Param(param) => {
793                    let generics = self.tcx.generics_of(generic_param_scope);
794                    let type_param = generics.type_param(param, self.tcx);
795                    let def_id = type_param.def_id.expect_local();
796                    let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id;
797                    // Get the `hir::Param` to verify whether it already has any bounds.
798                    // We do this to avoid suggesting code that ends up as `T: 'a'b`,
799                    // instead we suggest `T: 'a + 'b` in that case.
800                    let hir_generics = self.tcx.hir_get_generics(scope).unwrap();
801                    let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) {
802                        Some((span, open_paren_sp)) => {
803                            Some((span, LifetimeSuggestion::NeedsPlus(open_paren_sp)))
804                        }
805                        // If `param` corresponds to `Self`, no usable suggestion span.
806                        None if generics.has_self && param.index == 0 => None,
807                        None => {
808                            let mut colon_flag = false;
809                            let span = if let Some(param) =
810                                hir_generics.params.iter().find(|param| param.def_id == def_id)
811                                && let ParamName::Plain(ident) = param.name
812                            {
813                                if let Some(sp) = param.colon_span {
814                                    colon_flag = true;
815                                    sp.shrink_to_hi()
816                                } else {
817                                    ident.span.shrink_to_hi()
818                                }
819                            } else {
820                                let span = self.tcx.def_span(def_id);
821                                span.shrink_to_hi()
822                            };
823                            match colon_flag {
824                                true => Some((span, LifetimeSuggestion::HasColon)),
825                                false => Some((span, LifetimeSuggestion::NeedsColon)),
826                            }
827                        }
828                    };
829                    (scope, sugg_span)
830                }
831                _ => (generic_param_scope, None),
832            };
833            let suggestion_scope = {
834                let lifetime_scope = match sub.kind() {
835                    ty::ReStatic => hir::def_id::CRATE_DEF_ID,
836                    _ => match self.tcx.is_suitable_region(generic_param_scope, sub) {
837                        Some(info) => info.scope,
838                        None => generic_param_scope,
839                    },
840                };
841                match self.tcx.is_descendant_of(type_scope, lifetime_scope) {
842                    true => type_scope,
843                    false => lifetime_scope,
844                }
845            };
846
847            let mut suggs = ::alloc::vec::Vec::new()vec![];
848            let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs);
849
850            if let Some((sp, suggestion_type)) = type_param_sugg_span
851                && suggestion_scope == type_scope
852            {
853                match suggestion_type {
854                    LifetimeSuggestion::NeedsPlus(open_paren_sp) => {
855                        let suggestion = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" + {0}", lt_name))
    })format!(" + {lt_name}");
856                        if let Some(open_paren_sp) = open_paren_sp {
857                            suggs.push((open_paren_sp, "(".to_string()));
858                            suggs.push((sp, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("){0}", suggestion))
    })format!("){suggestion}")));
859                        } else {
860                            suggs.push((sp, suggestion));
861                        }
862                    }
863                    LifetimeSuggestion::NeedsColon => suggs.push((sp, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": {0}", lt_name))
    })format!(": {lt_name}"))),
864                    LifetimeSuggestion::HasColon => suggs.push((sp, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" {0}", lt_name))
    })format!(" {lt_name}"))),
865                }
866            } else if let GenericKind::Alias(ref p) = bound_kind
867                && let ty::Projection { def_id } = p.kind
868                && let DefKind::AssocTy = self.tcx.def_kind(def_id)
869                && let Some(ty::ImplTraitInTraitData::Trait { .. }) =
870                    self.tcx.opt_rpitit_info(def_id)
871            {
872                // The lifetime found in the `impl` is longer than the one on the RPITIT.
873                // Do not suggest `<Type as Trait>::{opaque}: 'static`.
874            } else if let Some(generics) = self.tcx.hir_get_generics(suggestion_scope) {
875                let pred = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}: {1}", bound_kind, lt_name))
    })format!("{bound_kind}: {lt_name}");
876                let suggestion = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} {1}",
                generics.add_where_or_trailing_comma(), pred))
    })format!("{} {}", generics.add_where_or_trailing_comma(), pred);
877                suggs.push((generics.tail_span_for_predicate_suggestion(), suggestion))
878            } else {
879                let consider = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} `{1}: {2}`...", msg,
                bound_kind, sub))
    })format!("{msg} `{bound_kind}: {sub}`...");
880                err.help(consider);
881            }
882
883            if !suggs.is_empty() {
884                err.multipart_suggestion(
885                    msg,
886                    suggs,
887                    Applicability::MaybeIncorrect, // Issue #41966
888                );
889            }
890        }
891
892        if sub.kind() == ty::ReStatic
893            && let Some(node) = self.tcx.hir_get_if_local(generic_param_scope.into())
894            && let hir::Node::Item(hir::Item {
895                kind: hir::ItemKind::Fn { sig, body, has_body: true, .. },
896                ..
897            })
898            | hir::Node::TraitItem(hir::TraitItem {
899                kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)),
900                ..
901            })
902            | hir::Node::ImplItem(hir::ImplItem {
903                kind: hir::ImplItemKind::Fn(sig, body), ..
904            }) = node
905            && let hir::Node::Expr(expr) = self.tcx.hir_node(body.hir_id)
906            && let hir::ExprKind::Block(block, _) = expr.kind
907            && let Some(tail) = block.expr
908            && tail.span == span
909            && let hir::FnRetTy::Return(ty) = sig.decl.output
910            && let hir::TyKind::Path(path) = ty.kind
911            && let hir::QPath::Resolved(None, path) = path
912            && let hir::def::Res::Def(_, def_id) = path.res
913            && Some(def_id) == self.tcx.lang_items().owned_box()
914            && let [segment] = path.segments
915            && let Some(args) = segment.args
916            && let [hir::GenericArg::Type(ty)] = args.args
917            && let hir::TyKind::TraitObject(_, tagged_ref) = ty.kind
918            && let hir::LifetimeKind::ImplicitObjectLifetimeDefault = tagged_ref.pointer().kind
919        {
920            // Explicitly look for `-> Box<dyn Trait>` to point at it as the *likely* source of
921            // the `'static` lifetime requirement.
922            err.span_label(
923                ty.span,
924                ::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"),
925            );
926        }
927
928        err
929    }
930
931    pub fn suggest_name_region(
932        &self,
933        generic_param_scope: LocalDefId,
934        lifetime: Region<'tcx>,
935        add_lt_suggs: &mut Vec<(Span, String)>,
936    ) -> String {
937        struct LifetimeReplaceVisitor<'a> {
938            needle: hir::LifetimeKind,
939            new_lt: &'a str,
940            add_lt_suggs: &'a mut Vec<(Span, String)>,
941        }
942
943        impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> {
944            fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
945                if lt.kind == self.needle {
946                    self.add_lt_suggs.push(lt.suggestion(self.new_lt));
947                }
948            }
949        }
950
951        let (lifetime_def_id, lifetime_scope) =
952            match self.tcx.is_suitable_region(generic_param_scope, lifetime) {
953                Some(info) if !lifetime.is_named(self.tcx) => {
954                    (info.region_def_id.expect_local(), info.scope)
955                }
956                _ => return lifetime.get_name_or_anon(self.tcx).to_string(),
957            };
958
959        let new_lt = {
960            let generics = self.tcx.generics_of(lifetime_scope);
961            let mut used_names =
962                iter::successors(Some(generics), |g| g.parent.map(|p| self.tcx.generics_of(p)))
963                    .flat_map(|g| &g.own_params)
964                    .filter(|p| #[allow(non_exhaustive_omitted_patterns)] match p.kind {
    ty::GenericParamDefKind::Lifetime => true,
    _ => false,
}matches!(p.kind, ty::GenericParamDefKind::Lifetime))
965                    .map(|p| p.name)
966                    .collect::<Vec<_>>();
967            let hir_id = self.tcx.local_def_id_to_hir_id(lifetime_scope);
968            // consider late-bound lifetimes ...
969            used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map(
970                |p| match p {
971                    ty::BoundVariableKind::Region(lt) => lt.get_name(self.tcx),
972                    _ => None,
973                },
974            ));
975            (b'a'..=b'z')
976                .map(|c| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("\'{0}", c as char))
    })format!("'{}", c as char))
977                .find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate))
978                .unwrap_or_else(|| "'lt".to_string())
979        };
980
981        let mut visitor = LifetimeReplaceVisitor {
982            needle: hir::LifetimeKind::Param(lifetime_def_id),
983            add_lt_suggs,
984            new_lt: &new_lt,
985        };
986        match self.tcx.expect_hir_owner_node(lifetime_scope) {
987            hir::OwnerNode::Item(i) => visitor.visit_item(i),
988            hir::OwnerNode::ForeignItem(i) => visitor.visit_foreign_item(i),
989            hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i),
990            hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i),
991            hir::OwnerNode::Crate(_) => ::rustc_span::macros::bug_impl(None,
    format_args!("OwnerNode::Crate doesn\'t not have generics"),
    Location::caller())bug!("OwnerNode::Crate doesn't not have generics"),
992            hir::OwnerNode::Synthetic => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
993        }
994
995        let ast_generics = self.tcx.hir_get_generics(lifetime_scope).unwrap();
996        let sugg = ast_generics
997            .span_for_lifetime_suggestion()
998            .map(|span| (span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}, ", new_lt))
    })format!("{new_lt}, ")))
999            .unwrap_or_else(|| (ast_generics.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}>", new_lt))
    })format!("<{new_lt}>")));
1000        add_lt_suggs.push(sugg);
1001
1002        new_lt
1003    }
1004
1005    fn report_sub_sup_conflict(
1006        &self,
1007        generic_param_scope: LocalDefId,
1008        var_origin: RegionVariableOrigin<'tcx>,
1009        sub_origin: SubregionOrigin<'tcx>,
1010        sub_region: Region<'tcx>,
1011        sup_origin: SubregionOrigin<'tcx>,
1012        sup_region: Region<'tcx>,
1013    ) -> ErrorGuaranteed {
1014        let mut err = self.report_inference_failure(var_origin);
1015
1016        note_and_explain_region(
1017            self.tcx,
1018            &mut err,
1019            generic_param_scope,
1020            "first, the lifetime cannot outlive ",
1021            sup_region,
1022            "...",
1023            None,
1024        );
1025
1026        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1026",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(1026u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: var_origin={0:?}",
                                                    var_origin) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
1027        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1027",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(1027u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sub_region={0:?}",
                                                    sub_region) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
1028        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1028",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(1028u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sub_origin={0:?}",
                                                    sub_origin) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
1029        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1029",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(1029u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sup_region={0:?}",
                                                    sup_region) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
1030        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:1030",
                        "rustc_trait_selection::error_reporting::infer::region",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                        ::tracing_core::__macro_support::Option::Some(1030u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("report_sub_sup_conflict: sup_origin={0:?}",
                                                    sup_origin) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
1031
1032        if let SubregionOrigin::Subtype(ref sup_trace) = sup_origin
1033            && let SubregionOrigin::Subtype(ref sub_trace) = sub_origin
1034            && let Some((sup_expected, sup_found)) =
1035                self.values_str(sup_trace.values, &sup_trace.cause, err.long_ty_path())
1036            && let Some((sub_expected, sub_found)) =
1037                self.values_str(sub_trace.values, &sub_trace.cause, err.long_ty_path())
1038            && sub_expected == sup_expected
1039            && sub_found == sup_found
1040        {
1041            note_and_explain_region(
1042                self.tcx,
1043                &mut err,
1044                generic_param_scope,
1045                "...but the lifetime must also be valid for ",
1046                sub_region,
1047                "...",
1048                None,
1049            );
1050            err.span_note(
1051                sup_trace.cause.span,
1052                ::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()),
1053            );
1054
1055            err.note_expected_found("", sup_expected, "", sup_found);
1056            return if sub_region.is_error() | sup_region.is_error() {
1057                err.delay_as_bug()
1058            } else {
1059                err.emit_err()
1060            };
1061        }
1062
1063        self.note_region_origin(&mut err, &sup_origin);
1064
1065        note_and_explain_region(
1066            self.tcx,
1067            &mut err,
1068            generic_param_scope,
1069            "but, the lifetime must be valid for ",
1070            sub_region,
1071            "...",
1072            None,
1073        );
1074
1075        self.note_region_origin(&mut err, &sub_origin);
1076        if sub_region.is_error() | sup_region.is_error() {
1077            err.delay_as_bug()
1078        } else {
1079            err.emit_err()
1080        }
1081    }
1082
1083    fn report_inference_failure(&self, var_origin: RegionVariableOrigin<'tcx>) -> Diag<'_> {
1084        let br_string = |br: ty::BoundRegionKind<'tcx>| {
1085            let mut s = match br {
1086                ty::BoundRegionKind::Named(def_id) => self.tcx.item_name(def_id).to_string(),
1087                _ => String::new(),
1088            };
1089            if !s.is_empty() {
1090                s.push(' ');
1091            }
1092            s
1093        };
1094        let var_description = match var_origin {
1095            RegionVariableOrigin::Misc(_) => String::new(),
1096            RegionVariableOrigin::PatternRegion(_) => " for pattern".to_string(),
1097            RegionVariableOrigin::BorrowRegion(_) => " for borrow expression".to_string(),
1098            RegionVariableOrigin::Autoref(_) => " for autoref".to_string(),
1099            RegionVariableOrigin::Coercion(_) => " for automatic coercion".to_string(),
1100            RegionVariableOrigin::BoundRegion(_, br, BoundRegionConversionTime::FnCall) => {
1101                ::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))
1102            }
1103            RegionVariableOrigin::BoundRegion(
1104                _,
1105                br,
1106                BoundRegionConversionTime::HigherRankedType,
1107            ) => {
1108                ::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))
1109            }
1110            RegionVariableOrigin::BoundRegion(
1111                _,
1112                br,
1113                BoundRegionConversionTime::AssocTypeProjection(def_id),
1114            ) => ::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!(
1115                " for lifetime parameter {}in trait containing associated type `{}`",
1116                br_string(br),
1117                self.tcx.associated_item(def_id).name()
1118            ),
1119            RegionVariableOrigin::RegionParameterDefinition(_, name) => {
1120                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" for lifetime parameter `{0}`",
                name))
    })format!(" for lifetime parameter `{name}`")
1121            }
1122            RegionVariableOrigin::UpvarRegion(ref upvar_id, _) => {
1123                let var_name = self.tcx.hir_name(upvar_id.var_path.hir_id);
1124                ::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")
1125            }
1126            RegionVariableOrigin::Nll(..) => ::rustc_span::macros::bug_impl(None,
    format_args!("NLL variable found in lexical phase"), Location::caller())bug!("NLL variable found in lexical phase"),
1127        };
1128
1129        {
    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!(
1130            self.dcx(),
1131            var_origin.span(),
1132            E0803,
1133            "cannot infer an appropriate lifetime{} due to conflicting requirements",
1134            var_description
1135        )
1136    }
1137}
1138
1139enum LifetimeSuggestion {
1140    NeedsPlus(Option<Span>),
1141    NeedsColon,
1142    HasColon,
1143}
1144
1145pub(super) fn note_and_explain_region<'tcx>(
1146    tcx: TyCtxt<'tcx>,
1147    err: &mut Diag<'_>,
1148    generic_param_scope: LocalDefId,
1149    prefix: &str,
1150    region: ty::Region<'tcx>,
1151    suffix: &str,
1152    alt_span: Option<Span>,
1153) {
1154    let (description, span) = match region.kind() {
1155        ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
1156            msg_span_from_named_region(tcx, generic_param_scope, region, alt_span)
1157        }
1158
1159        ty::ReError(_) => return,
1160
1161        // FIXME(#125431): `ReVar` shouldn't reach here.
1162        ty::ReVar(_) => (::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("lifetime `{0}`", region))
    })format!("lifetime `{region}`"), alt_span),
1163
1164        ty::ReBound(..) | ty::ReErased => {
1165            ::rustc_span::macros::bug_impl(None,
    format_args!("unexpected region for note_and_explain_region: {0:?}",
        region), Location::caller());bug!("unexpected region for note_and_explain_region: {:?}", region);
1166        }
1167    };
1168
1169    emit_msg_span(err, prefix, description, span, suffix);
1170}
1171
1172fn explain_free_region<'tcx>(
1173    tcx: TyCtxt<'tcx>,
1174    err: &mut Diag<'_>,
1175    generic_param_scope: LocalDefId,
1176    prefix: &str,
1177    region: ty::Region<'tcx>,
1178    suffix: &str,
1179) {
1180    let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None);
1181
1182    label_msg_span(err, prefix, description, span, suffix);
1183}
1184
1185fn msg_span_from_named_region<'tcx>(
1186    tcx: TyCtxt<'tcx>,
1187    generic_param_scope: LocalDefId,
1188    region: ty::Region<'tcx>,
1189    alt_span: Option<Span>,
1190) -> (String, Option<Span>) {
1191    match region.kind() {
1192        ty::ReEarlyParam(br) => {
1193            let param_def_id = tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id;
1194            let span = tcx.def_span(param_def_id);
1195            let text = if br.is_named() {
1196                ::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)
1197            } else {
1198                "the anonymous lifetime as defined here".to_string()
1199            };
1200            (text, Some(span))
1201        }
1202        ty::ReLateParam(ref fr) => {
1203            if !fr.kind.is_named(tcx)
1204                && let Some((ty, _)) = find_anon_type(tcx, generic_param_scope, region)
1205            {
1206                ("the anonymous lifetime defined here".to_string(), Some(ty.span))
1207            } else {
1208                match fr.kind {
1209                    ty::LateParamRegionKind::Named(param_def_id) => {
1210                        let name = tcx.item_name(param_def_id);
1211                        let span = tcx.def_span(param_def_id);
1212                        let text = if name == kw::UnderscoreLifetime {
1213                            "the anonymous lifetime as defined here".to_string()
1214                        } else {
1215                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the lifetime `{0}` as defined here",
                name))
    })format!("the lifetime `{name}` as defined here")
1216                        };
1217                        (text, Some(span))
1218                    }
1219                    ty::LateParamRegionKind::Anon(_) => (
1220                        "the anonymous lifetime as defined here".to_string(),
1221                        Some(tcx.def_span(generic_param_scope)),
1222                    ),
1223                    _ => (
1224                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the lifetime `{0}` as defined here",
                region))
    })format!("the lifetime `{region}` as defined here"),
1225                        Some(tcx.def_span(generic_param_scope)),
1226                    ),
1227                }
1228            }
1229        }
1230        ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
1231        ty::RePlaceholder(ty::PlaceholderRegion {
1232            bound: ty::BoundRegion { kind: ty::BoundRegionKind::Named(def_id), .. },
1233            ..
1234        }) => (
1235            ::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)),
1236            Some(tcx.def_span(def_id)),
1237        ),
1238        ty::RePlaceholder(ty::PlaceholderRegion {
1239            bound: ty::BoundRegion { kind: ty::BoundRegionKind::Anon, .. },
1240            ..
1241        }) => ("an anonymous lifetime".to_owned(), None),
1242        _ => ::rustc_span::macros::bug_impl(None, format_args!("{0:?}", region),
    Location::caller())bug!("{:?}", region),
1243    }
1244}
1245
1246fn emit_msg_span(
1247    err: &mut Diag<'_>,
1248    prefix: &str,
1249    description: String,
1250    span: Option<Span>,
1251    suffix: &str,
1252) {
1253    let message = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}{2}", prefix, description,
                suffix))
    })format!("{prefix}{description}{suffix}");
1254
1255    if let Some(span) = span {
1256        err.span_note(span, message);
1257    } else {
1258        err.note(message);
1259    }
1260}
1261
1262fn label_msg_span(
1263    err: &mut Diag<'_>,
1264    prefix: &str,
1265    description: String,
1266    span: Option<Span>,
1267    suffix: &str,
1268) {
1269    let message = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}{2}", prefix, description,
                suffix))
    })format!("{prefix}{description}{suffix}");
1270
1271    if let Some(span) = span {
1272        err.span_label(span, message);
1273    } else {
1274        err.note(message);
1275    }
1276}
1277
1278{}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("unexpected_hidden_region_diagnostic",
                                    "rustc_trait_selection::error_reporting::infer::region",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1278u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::region"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("generic_param_scope")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("generic_param_scope");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("span")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("span");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("hidden_ty")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("hidden_ty");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("hidden_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("hidden_region");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("opaque_ty_key")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("opaque_ty_key");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&generic_param_scope)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hidden_ty)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hidden_region)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&opaque_ty_key)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Diag<'a> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let tcx = infcx.tcx;
            let mut err =
                infcx.dcx().create_err(diagnostics::OpaqueCapturesLifetime {
                        span,
                        opaque_ty: Ty::new_opaque(tcx, ty::IsRigid::No,
                            opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args),
                        opaque_ty_span: tcx.def_span(opaque_ty_key.def_id),
                    });
            let mut highlight = RegionHighlightMode::default();
            highlight.keep_regions = true;
            let hidden_ty =
                Highlighted {
                    highlight,
                    ns: Namespace::TypeNS,
                    tcx,
                    value: hidden_ty,
                };
            match hidden_region.kind() {
                ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
                    explain_free_region(tcx, &mut err, generic_param_scope,
                        &::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("hidden type `{0}` captures ",
                                            hidden_ty))
                                }), hidden_region, "");
                    if let Some(_) =
                            tcx.is_suitable_region(generic_param_scope, hidden_region) {
                        suggest_precise_capturing(tcx, opaque_ty_key.def_id,
                            hidden_region, &mut err);
                    }
                }
                ty::RePlaceholder(_) => {
                    explain_free_region(tcx, &mut err, generic_param_scope,
                        &::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("hidden type `{0}` captures ",
                                            hidden_ty))
                                }), hidden_region, "");
                }
                ty::ReError(_) => { err.downgrade_to_delayed_bug(); }
                _ => {
                    note_and_explain_region(tcx, &mut err, generic_param_scope,
                        &::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("hidden type `{0}` captures ",
                                            hidden_ty))
                                }), hidden_region, "", None);
                }
            }
            err
        }
    }
}#[instrument(level = "trace", skip(infcx))]
1279pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>(
1280    infcx: &'a InferCtxt<'tcx>,
1281    generic_param_scope: LocalDefId,
1282    span: Span,
1283    hidden_ty: Ty<'tcx>,
1284    hidden_region: ty::Region<'tcx>,
1285    opaque_ty_key: ty::OpaqueTypeKey<'tcx>,
1286) -> Diag<'a> {
1287    let tcx = infcx.tcx;
1288    let mut err = infcx.dcx().create_err(diagnostics::OpaqueCapturesLifetime {
1289        span,
1290        opaque_ty: Ty::new_opaque(
1291            tcx,
1292            ty::IsRigid::No,
1293            opaque_ty_key.def_id.to_def_id(),
1294            opaque_ty_key.args,
1295        ),
1296        opaque_ty_span: tcx.def_span(opaque_ty_key.def_id),
1297    });
1298    let mut highlight = RegionHighlightMode::default();
1299    highlight.keep_regions = true;
1300    let hidden_ty = Highlighted { highlight, ns: Namespace::TypeNS, tcx, value: hidden_ty };
1301
1302    // Explain the region we are capturing.
1303    match hidden_region.kind() {
1304        ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
1305            // Assuming regionck succeeded (*), we ought to always be
1306            // capturing *some* region from the fn header, and hence it
1307            // ought to be free. So under normal circumstances, we will go
1308            // down this path which gives a decent human readable
1309            // explanation.
1310            //
1311            // (*) if not, the `tainted_by_errors` field would be set to
1312            // `Some(ErrorGuaranteed)` in any case, so we wouldn't be here at all.
1313            explain_free_region(
1314                tcx,
1315                &mut err,
1316                generic_param_scope,
1317                &format!("hidden type `{hidden_ty}` captures "),
1318                hidden_region,
1319                "",
1320            );
1321            if let Some(_) = tcx.is_suitable_region(generic_param_scope, hidden_region) {
1322                suggest_precise_capturing(tcx, opaque_ty_key.def_id, hidden_region, &mut err);
1323            }
1324        }
1325        ty::RePlaceholder(_) => {
1326            explain_free_region(
1327                tcx,
1328                &mut err,
1329                generic_param_scope,
1330                &format!("hidden type `{}` captures ", hidden_ty),
1331                hidden_region,
1332                "",
1333            );
1334        }
1335        ty::ReError(_) => {
1336            err.downgrade_to_delayed_bug();
1337        }
1338        _ => {
1339            // Ugh. This is a painful case: the hidden region is not one
1340            // that we can easily summarize or explain. This can happen
1341            // in a case like
1342            // `tests/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`:
1343            //
1344            // ```
1345            // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> {
1346            //   if condition() { a } else { b }
1347            // }
1348            // ```
1349            //
1350            // Here the captured lifetime is the intersection of `'a` and
1351            // `'b`, which we can't quite express.
1352
1353            // We can at least report a really cryptic error for now.
1354            note_and_explain_region(
1355                tcx,
1356                &mut err,
1357                generic_param_scope,
1358                &format!("hidden type `{hidden_ty}` captures "),
1359                hidden_region,
1360                "",
1361                None,
1362            );
1363        }
1364    }
1365
1366    err
1367}
1368
1369fn suggest_precise_capturing<'tcx>(
1370    tcx: TyCtxt<'tcx>,
1371    opaque_def_id: LocalDefId,
1372    captured_lifetime: ty::Region<'tcx>,
1373    diag: &mut Diag<'_>,
1374) {
1375    let hir::OpaqueTy { bounds, origin, .. } =
1376        tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
1377
1378    let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
1379        return;
1380    };
1381
1382    let new_lifetime = Symbol::intern(&captured_lifetime.to_string());
1383
1384    if let Some((args, span)) = bounds.iter().find_map(|bound| match bound {
1385        hir::GenericBound::Use(args, span) => Some((args, span)),
1386        _ => None,
1387    }) {
1388        // '_ is an elision marker, not a lifetime name, so it cannot appear twice in a
1389        // capture list. the branch for opaques with no use<..> yet already skips captured
1390        // lifetimes; do the same here to avoid suggesting use<'_, '_>.
1391        if args.iter().any(|arg| {
1392            #[allow(non_exhaustive_omitted_patterns)] match arg {
    hir::PreciseCapturingArg::Lifetime(lt) if lt.ident.name == new_lifetime =>
        true,
    _ => false,
}matches!(arg, hir::PreciseCapturingArg::Lifetime(lt) if lt.ident.name == new_lifetime)
1393        }) {
1394            return;
1395        }
1396
1397        let last_lifetime_span = args.iter().rev().find_map(|arg| match arg {
1398            hir::PreciseCapturingArg::Lifetime(lt) => Some(lt.ident.span),
1399            _ => None,
1400        });
1401
1402        let first_param_span = args.iter().find_map(|arg| match arg {
1403            hir::PreciseCapturingArg::Param(p) => Some(p.ident.span),
1404            _ => None,
1405        });
1406
1407        let (span, pre, post) = if let Some(last_lifetime_span) = last_lifetime_span {
1408            (last_lifetime_span.shrink_to_hi(), ", ", "")
1409        } else if let Some(first_param_span) = first_param_span {
1410            (first_param_span.shrink_to_lo(), "", ", ")
1411        } else {
1412            // If we have no args, then have `use<>` and need to fall back to using
1413            // span math. This sucks, but should be reliable due to the construction
1414            // of the `use<>` span.
1415            (span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(), "", "")
1416        };
1417
1418        diag.subdiagnostic(diagnostics::AddPreciseCapturing::Existing {
1419            span,
1420            new_lifetime,
1421            pre,
1422            post,
1423        });
1424    } else {
1425        let mut captured_lifetimes = FxIndexSet::default();
1426        let mut captured_non_lifetimes = FxIndexSet::default();
1427
1428        let variances = tcx.variances_of(opaque_def_id);
1429        let mut generics = tcx.generics_of(opaque_def_id);
1430        let mut synthetics = ::alloc::vec::Vec::new()vec![];
1431        loop {
1432            for param in &generics.own_params {
1433                if variances[param.index as usize] == ty::Bivariant {
1434                    continue;
1435                }
1436
1437                match param.kind {
1438                    ty::GenericParamDefKind::Lifetime => {
1439                        captured_lifetimes.insert(param.name);
1440                    }
1441                    ty::GenericParamDefKind::Type { synthetic: true, .. } => {
1442                        synthetics.push((tcx.def_span(param.def_id), param.name));
1443                    }
1444                    ty::GenericParamDefKind::Type { .. }
1445                    | ty::GenericParamDefKind::Const { .. } => {
1446                        captured_non_lifetimes.insert(param.name);
1447                    }
1448                }
1449            }
1450
1451            if let Some(parent) = generics.parent {
1452                generics = tcx.generics_of(parent);
1453            } else {
1454                break;
1455            }
1456        }
1457
1458        if !captured_lifetimes.insert(new_lifetime) {
1459            // Uh, strange. This lifetime appears to already be captured...
1460            return;
1461        }
1462
1463        if synthetics.is_empty() {
1464            let concatenated_bounds = captured_lifetimes
1465                .into_iter()
1466                .chain(captured_non_lifetimes)
1467                .map(|sym| sym.to_string())
1468                .collect::<Vec<_>>()
1469                .join(", ");
1470
1471            diag.subdiagnostic(diagnostics::AddPreciseCapturing::New {
1472                span: tcx.def_span(opaque_def_id).shrink_to_hi(),
1473                new_lifetime,
1474                concatenated_bounds,
1475            });
1476        } else {
1477            let mut next_fresh_param = || {
1478                ['T', 'U', 'V', 'W', 'X', 'Y', 'A', 'B', 'C']
1479                    .into_iter()
1480                    .map(sym::character)
1481                    .chain((0..).map(|i| Symbol::intern(&::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("T{0}", i)) })format!("T{i}"))))
1482                    .find(|s| captured_non_lifetimes.insert(*s))
1483                    .unwrap()
1484            };
1485
1486            let mut new_params = String::new();
1487            let mut suggs = ::alloc::vec::Vec::new()vec![];
1488            let mut apit_spans = ::alloc::vec::Vec::new()vec![];
1489
1490            for (i, (span, name)) in synthetics.into_iter().enumerate() {
1491                apit_spans.push(span);
1492
1493                let fresh_param = next_fresh_param();
1494
1495                // Suggest renaming.
1496                suggs.push((span, fresh_param.to_string()));
1497
1498                // Super jank. Turn `impl Trait` into `T: Trait`.
1499                //
1500                // This currently involves stripping the `impl` from the name of
1501                // the parameter, since APITs are always named after how they are
1502                // rendered in the AST. This sucks! But to recreate the bound list
1503                // from the APIT itself would be miserable, so we're stuck with
1504                // this for now!
1505                if i > 0 {
1506                    new_params += ", ";
1507                }
1508                let name_as_bounds = name.as_str().trim_start_matches("impl").trim_start();
1509                new_params += fresh_param.as_str();
1510                new_params += ": ";
1511                new_params += name_as_bounds;
1512            }
1513
1514            let Some(generics) = tcx.hir_get_generics(fn_def_id) else {
1515                // This shouldn't happen, but don't ICE.
1516                return;
1517            };
1518
1519            // Add generics or concatenate to the end of the list.
1520            suggs.push(if let Some(params_span) = generics.span_for_param_suggestion() {
1521                (params_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(", {0}", new_params))
    })format!(", {new_params}"))
1522            } else {
1523                (generics.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("<{0}>", new_params))
    })format!("<{new_params}>"))
1524            });
1525
1526            let concatenated_bounds = captured_lifetimes
1527                .into_iter()
1528                .chain(captured_non_lifetimes)
1529                .map(|sym| sym.to_string())
1530                .collect::<Vec<_>>()
1531                .join(", ");
1532
1533            suggs.push((
1534                tcx.def_span(opaque_def_id).shrink_to_hi(),
1535                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" + use<{0}>", concatenated_bounds))
    })format!(" + use<{concatenated_bounds}>"),
1536            ));
1537
1538            diag.subdiagnostic(diagnostics::AddPreciseCapturingAndParams {
1539                suggs,
1540                new_lifetime,
1541                apit_spans,
1542            });
1543        }
1544    }
1545}