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

    #[warn(clippy :: suspicious_else_formatting)]
    {

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