Skip to main content

rustc_infer/infer/outlives/
verify.rs

1use rustc_data_structures::assert_matches;
2use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive};
3use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
4use smallvec::smallvec;
5use tracing::{debug, instrument, trace};
6
7use crate::infer::outlives::env::RegionBoundPairs;
8use crate::infer::region_constraints::VerifyIfEq;
9use crate::infer::{GenericKind, VerifyBound};
10
11/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
12/// obligation into a series of `'a: 'b` constraints and "verifys", as
13/// described on the module comment. The final constraints are emitted
14/// via a "delegate" of type `D` -- this is usually the `infcx`, which
15/// accrues them into the `region_obligations` code, but for NLL we
16/// use something else.
17pub(crate) struct VerifyBoundCx<'cx, 'tcx> {
18    tcx: TyCtxt<'tcx>,
19    region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
20    /// During borrowck, if there are no outlives bounds on a generic
21    /// parameter `T`, we assume that `T: 'in_fn_body` holds.
22    ///
23    /// Outside of borrowck the only way to prove `T: '?0` is by
24    /// setting  `'?0` to `'empty`.
25    implicit_region_bound: Option<ty::Region<'tcx>>,
26    caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
27}
28
29impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
30    pub(crate) fn new(
31        tcx: TyCtxt<'tcx>,
32        region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
33        implicit_region_bound: Option<ty::Region<'tcx>>,
34        caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
35    ) -> Self {
36        Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds }
37    }
38
39    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("param_or_placeholder_bound",
                                    "rustc_infer::infer::outlives::verify",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                    ::tracing_core::__macro_support::Option::Some(39u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                    ::tracing_core::field::FieldSet::new(&["ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: VerifyBound<'tcx> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let declared_bounds_from_env =
                self.declared_generic_bounds_from_env(ty);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/outlives/verify.rs:45",
                                    "rustc_infer::infer::outlives::verify",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                    ::tracing_core::__macro_support::Option::Some(45u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                    ::tracing_core::field::FieldSet::new(&["declared_bounds_from_env"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&declared_bounds_from_env)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let mut param_bounds = ::alloc::vec::Vec::new();
            for declared_bound in declared_bounds_from_env {
                let bound_region =
                    declared_bound.map_bound(|outlives| outlives.1);
                if let Some(region) = bound_region.no_bound_vars() {
                    param_bounds.push(VerifyBound::OutlivedBy(region));
                } else {
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/outlives/verify.rs:54",
                                            "rustc_infer::infer::outlives::verify",
                                            ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                            ::tracing_core::__macro_support::Option::Some(54u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("found that {0:?} outlives any lifetime, returning empty vector",
                                                                        ty) as &dyn Value))])
                                });
                        } else { ; }
                    };
                    return VerifyBound::AllBounds(::alloc::vec::Vec::new());
                }
            }
            if let Some(r) = self.implicit_region_bound {
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/outlives/verify.rs:62",
                                        "rustc_infer::infer::outlives::verify",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                        ::tracing_core::__macro_support::Option::Some(62u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                        ::tracing_core::field::FieldSet::new(&["message"],
                                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                        ::tracing::metadata::Kind::EVENT)
                                };
                            ::tracing::callsite::DefaultCallsite::new(&META)
                        };
                    let enabled =
                        ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            {
                                let interest = __CALLSITE.interest();
                                !interest.is_never() &&
                                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                        interest)
                            };
                    if enabled {
                        (|value_set: ::tracing::field::ValueSet|
                                    {
                                        let meta = __CALLSITE.metadata();
                                        ::tracing::Event::dispatch(meta, &value_set);
                                        ;
                                    })({
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = __CALLSITE.metadata().fields().iter();
                                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&format_args!("adding implicit region bound of {0:?}",
                                                                    r) as &dyn Value))])
                            });
                    } else { ; }
                };
                param_bounds.push(VerifyBound::OutlivedBy(r));
            }
            if param_bounds.is_empty() {
                VerifyBound::IsEmpty
            } else if param_bounds.len() == 1 {
                param_bounds.pop().unwrap()
            } else { VerifyBound::AnyBound(param_bounds) }
        }
    }
}#[instrument(level = "debug", skip(self))]
40    pub(crate) fn param_or_placeholder_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
41        // Start with anything like `T: 'a` we can scrape from the
42        // environment. If the environment contains something like
43        // `for<'a> T: 'a`, then we know that `T` outlives everything.
44        let declared_bounds_from_env = self.declared_generic_bounds_from_env(ty);
45        debug!(?declared_bounds_from_env);
46        let mut param_bounds = vec![];
47        for declared_bound in declared_bounds_from_env {
48            let bound_region = declared_bound.map_bound(|outlives| outlives.1);
49            if let Some(region) = bound_region.no_bound_vars() {
50                // This is `T: 'a` for some free region `'a`.
51                param_bounds.push(VerifyBound::OutlivedBy(region));
52            } else {
53                // This is `for<'a> T: 'a`. This means that `T` outlives everything! All done here.
54                debug!("found that {ty:?} outlives any lifetime, returning empty vector");
55                return VerifyBound::AllBounds(vec![]);
56            }
57        }
58
59        // Add in the default bound of fn body that applies to all in
60        // scope type parameters:
61        if let Some(r) = self.implicit_region_bound {
62            debug!("adding implicit region bound of {r:?}");
63            param_bounds.push(VerifyBound::OutlivedBy(r));
64        }
65
66        if param_bounds.is_empty() {
67            // We know that all types `T` outlive `'empty`, so if we
68            // can find no other bound, then check that the region
69            // being tested is `'empty`.
70            VerifyBound::IsEmpty
71        } else if param_bounds.len() == 1 {
72            // Micro-opt: no need to store the vector if it's just len 1
73            param_bounds.pop().unwrap()
74        } else {
75            // If we can find any other bound `R` such that `T: R`, then
76            // we don't need to check for `'empty`, because `R: 'empty`.
77            VerifyBound::AnyBound(param_bounds)
78        }
79    }
80
81    /// Given a projection like `T::Item`, searches the environment
82    /// for where-clauses like `T::Item: 'a`. Returns the set of
83    /// regions `'a` that it finds.
84    ///
85    /// This is an "approximate" check -- it may not find all
86    /// applicable bounds, and not all the bounds it returns can be
87    /// relied upon. In particular, this check ignores region
88    /// identity. So, for example, if we have `<T as
89    /// Trait<'0>>::Item` where `'0` is a region variable, and the
90    /// user has `<T as Trait<'a>>::Item: 'b` in the environment, then
91    /// the clause from the environment only applies if `'0 = 'a`,
92    /// which we don't know yet. But we would still include `'b` in
93    /// this list.
94    pub(crate) fn approx_declared_bounds_from_env(
95        &self,
96        alias_ty: ty::AliasTy<'tcx>,
97    ) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
98        let erased_alias_ty = self.tcx.erase_and_anonymize_regions(alias_ty.to_ty(self.tcx));
99        self.declared_generic_bounds_from_env_for_erased_ty(erased_alias_ty)
100    }
101
102    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("alias_bound",
                                    "rustc_infer::infer::outlives::verify",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                    ::tracing_core::__macro_support::Option::Some(102u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                    ::tracing_core::field::FieldSet::new(&["alias_ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&alias_ty)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: VerifyBound<'tcx> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let env_bounds =
                self.approx_declared_bounds_from_env(alias_ty).into_iter().map(|binder|
                        {
                            if let Some(ty::OutlivesPredicate(ty, r)) =
                                            binder.no_bound_vars() &&
                                        let ty::Alias(_, alias_ty_from_bound) = *ty.kind() &&
                                    alias_ty_from_bound == alias_ty {
                                VerifyBound::OutlivedBy(r)
                            } else {
                                let verify_if_eq_b =
                                    binder.map_bound(|ty::OutlivesPredicate(ty, bound)|
                                            VerifyIfEq { ty, bound });
                                VerifyBound::IfEq(verify_if_eq_b)
                            }
                        });
            let definition_bounds =
                self.declared_bounds_from_definition(alias_ty).map(|r|
                        VerifyBound::OutlivedBy(r));
            let recursive_bound =
                {
                    let mut components = ::smallvec::SmallVec::new();
                    let kind = alias_ty.kind(self.tcx);
                    compute_alias_components_recursive(self.tcx, kind, alias_ty,
                        &mut components);
                    self.bound_from_components(&components)
                };
            VerifyBound::AnyBound(env_bounds.chain(definition_bounds).collect()).or(recursive_bound)
        }
    }
}#[instrument(level = "debug", skip(self))]
103    pub(crate) fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tcx> {
104        // Search the env for where clauses like `P: 'a`.
105        let env_bounds = self.approx_declared_bounds_from_env(alias_ty).into_iter().map(|binder| {
106            if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars()
107                && let ty::Alias(_, alias_ty_from_bound) = *ty.kind()
108                && alias_ty_from_bound == alias_ty
109            {
110                // Micro-optimize if this is an exact match (this
111                // occurs often when there are no region variables
112                // involved).
113                VerifyBound::OutlivedBy(r)
114            } else {
115                let verify_if_eq_b =
116                    binder.map_bound(|ty::OutlivesPredicate(ty, bound)| VerifyIfEq { ty, bound });
117                VerifyBound::IfEq(verify_if_eq_b)
118            }
119        });
120
121        // Extend with bounds that we can find from the definition.
122        let definition_bounds =
123            self.declared_bounds_from_definition(alias_ty).map(|r| VerifyBound::OutlivedBy(r));
124
125        // see the extensive comment in projection_must_outlive
126        let recursive_bound = {
127            let mut components = smallvec![];
128            let kind = alias_ty.kind(self.tcx);
129            compute_alias_components_recursive(self.tcx, kind, alias_ty, &mut components);
130            self.bound_from_components(&components)
131        };
132
133        VerifyBound::AnyBound(env_bounds.chain(definition_bounds).collect()).or(recursive_bound)
134    }
135
136    fn bound_from_components(&self, components: &[Component<TyCtxt<'tcx>>]) -> VerifyBound<'tcx> {
137        let mut bounds = components
138            .iter()
139            .map(|component| self.bound_from_single_component(component))
140            // Remove bounds that must hold, since they are not interesting.
141            .filter(|bound| !bound.must_hold());
142
143        match (bounds.next(), bounds.next()) {
144            (Some(first), None) => first,
145            (first, second) => {
146                VerifyBound::AllBounds(first.into_iter().chain(second).chain(bounds).collect())
147            }
148        }
149    }
150
151    fn bound_from_single_component(
152        &self,
153        component: &Component<TyCtxt<'tcx>>,
154    ) -> VerifyBound<'tcx> {
155        match *component {
156            Component::Region(lt) => VerifyBound::OutlivedBy(lt),
157            Component::Param(param_ty) => self.param_or_placeholder_bound(param_ty.to_ty(self.tcx)),
158            Component::Placeholder(placeholder_ty) => {
159                self.param_or_placeholder_bound(Ty::new_placeholder(self.tcx, placeholder_ty))
160            }
161            Component::Alias(alias_ty) => self.alias_bound(alias_ty),
162            Component::EscapingAlias(ref components) => self.bound_from_components(components),
163            Component::UnresolvedInferenceVariable(v) => {
164                // Ignore this, we presume it will yield an error later, since
165                // if a type variable is not resolved by this point it never
166                // will be.
167                self.tcx
168                    .dcx()
169                    .delayed_bug(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unresolved inference variable in outlives: {0:?}",
                v))
    })format!("unresolved inference variable in outlives: {v:?}"));
170                // Add a bound that never holds.
171                VerifyBound::AnyBound(::alloc::vec::Vec::new()vec![])
172            }
173        }
174    }
175
176    /// Searches the environment for where-clauses like `G: 'a` where
177    /// `G` is either some type parameter `T` or a projection like
178    /// `T::Item`. Returns a vector of the `'a` bounds it can find.
179    ///
180    /// This is a conservative check -- it may not find all applicable
181    /// bounds, but all the bounds it returns can be relied upon.
182    fn declared_generic_bounds_from_env(
183        &self,
184        generic_ty: Ty<'tcx>,
185    ) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
186        match generic_ty.kind() {
    ty::Param(_) | ty::Placeholder(_) => {}
    ref left_val => {
        ::core::panicking::assert_matches_failed(left_val,
            "ty::Param(_) | ty::Placeholder(_)",
            ::core::option::Option::None);
    }
};assert_matches!(generic_ty.kind(), ty::Param(_) | ty::Placeholder(_));
187        self.declared_generic_bounds_from_env_for_erased_ty(generic_ty)
188    }
189
190    /// Searches the environment to find all bounds that apply to `erased_ty`.
191    /// Obviously these must be approximate -- they are in fact both *over* and
192    /// and *under* approximated:
193    ///
194    /// * Over-approximated because we don't consider equality of regions.
195    /// * Under-approximated because we look for syntactic equality and so for complex types
196    ///   like `<T as Foo<fn(&u32, &u32)>>::Item` or whatever we may fail to figure out
197    ///   all the subtleties.
198    ///
199    /// In some cases, such as when `erased_ty` represents a `ty::Param`, however,
200    /// the result is precise.
201    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("declared_generic_bounds_from_env_for_erased_ty",
                                    "rustc_infer::infer::outlives::verify",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                    ::tracing_core::__macro_support::Option::Some(201u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                    ::tracing_core::field::FieldSet::new(&["erased_ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&erased_ty)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return:
                    Vec<ty::PolyTypeOutlivesPredicate<'tcx>> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let tcx = self.tcx;
            let mut bounds = ::alloc::vec::Vec::new();
            bounds.extend(self.caller_bounds.iter().copied().filter(move
                        |outlives_predicate|
                        {
                            super::test_type_match::can_match_erased_ty(tcx,
                                *outlives_predicate, erased_ty)
                        }));
            bounds.extend(self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p,
                            r)|
                        {
                            {
                                use ::tracing::__macro_support::Callsite as _;
                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                    {
                                        static META: ::tracing::Metadata<'static> =
                                            {
                                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/outlives/verify.rs:228",
                                                    "rustc_infer::infer::outlives::verify",
                                                    ::tracing::Level::DEBUG,
                                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                                                    ::tracing_core::__macro_support::Option::Some(228u32),
                                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                                                    ::tracing_core::field::FieldSet::new(&["message"],
                                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                    ::tracing::metadata::Kind::EVENT)
                                            };
                                        ::tracing::callsite::DefaultCallsite::new(&META)
                                    };
                                let enabled =
                                    ::tracing::Level::DEBUG <=
                                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                            ::tracing::Level::DEBUG <=
                                                ::tracing::level_filters::LevelFilter::current() &&
                                        {
                                            let interest = __CALLSITE.interest();
                                            !interest.is_never() &&
                                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                    interest)
                                        };
                                if enabled {
                                    (|value_set: ::tracing::field::ValueSet|
                                                {
                                                    let meta = __CALLSITE.metadata();
                                                    ::tracing::Event::dispatch(meta, &value_set);
                                                    ;
                                                })({
                                            #[allow(unused_imports)]
                                            use ::tracing::field::{debug, display, Value};
                                            let mut iter = __CALLSITE.metadata().fields().iter();
                                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                ::tracing::__macro_support::Option::Some(&format_args!("declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {0:?}",
                                                                                (r, p)) as &dyn Value))])
                                        });
                                } else { ; }
                            };
                            match (&p, erased_ty.kind()) {
                                (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
                                (GenericKind::Placeholder(p1), ty::Placeholder(p2)) if
                                    p1 == p2 => {}
                                (GenericKind::Alias(a1), ty::Alias(_, a2)) if
                                    a1.def_id == a2.def_id => {}
                                _ => return None,
                            }
                            let p_ty = p.to_ty(tcx);
                            let erased_p_ty =
                                self.tcx.erase_and_anonymize_regions(p_ty);
                            (erased_p_ty ==
                                        erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty,
                                        r)))
                        }));
            bounds
        }
    }
}#[instrument(level = "debug", skip(self))]
202    fn declared_generic_bounds_from_env_for_erased_ty(
203        &self,
204        erased_ty: Ty<'tcx>,
205    ) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
206        let tcx = self.tcx;
207        let mut bounds = vec![];
208
209        // To start, collect bounds from user environment. Note that
210        // parameter environments are already elaborated, so we don't
211        // have to worry about that.
212        bounds.extend(self.caller_bounds.iter().copied().filter(move |outlives_predicate| {
213            super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
214        }));
215
216        // Next, collect regions we scraped from the well-formedness
217        // constraints in the fn signature. To do that, we walk the list
218        // of known relations from the fn ctxt.
219        //
220        // This is crucial because otherwise code like this fails:
221        //
222        //     fn foo<'a, A>(x: &'a A) { x.bar() }
223        //
224        // The problem is that the type of `x` is `&'a A`. To be
225        // well-formed, then, A must outlive `'a`, but we don't know that
226        // this holds from first principles.
227        bounds.extend(self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
228            debug!(
229                "declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
230                (r, p)
231            );
232            // Fast path for the common case.
233            match (&p, erased_ty.kind()) {
234                // In outlive routines, all types are expected to be fully normalized.
235                // And therefore we can safely use structural equality for alias types.
236                (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
237                (GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {}
238                (GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {}
239                _ => return None,
240            }
241
242            let p_ty = p.to_ty(tcx);
243            let erased_p_ty = self.tcx.erase_and_anonymize_regions(p_ty);
244            (erased_p_ty == erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r)))
245        }));
246
247        bounds
248    }
249
250    /// Given a projection like `<T as Foo<'x>>::Bar`, returns any bounds
251    /// declared in the trait definition. For example, if the trait were
252    ///
253    /// ```rust
254    /// trait Foo<'a> {
255    ///     type Bar: 'a;
256    /// }
257    /// ```
258    ///
259    /// If we were given the `DefId` of `Foo::Bar`, we would return
260    /// `'a`. You could then apply the instantiations from the
261    /// projection to convert this into your namespace. This also
262    /// works if the user writes `where <Self as Foo<'a>>::Bar: 'a` on
263    /// the trait. In fact, it works by searching for just such a
264    /// where-clause.
265    ///
266    /// It will not, however, work for higher-ranked bounds like:
267    ///
268    /// ```ignore(this does compile today, previously was marked as `compile_fail,E0311`)
269    /// trait Foo<'a, 'b>
270    /// where for<'x> <Self as Foo<'x, 'b>>::Bar: 'x
271    /// {
272    ///     type Bar;
273    /// }
274    /// ```
275    ///
276    /// This is for simplicity, and because we are not really smart
277    /// enough to cope with such bounds anywhere.
278    pub(crate) fn declared_bounds_from_definition(
279        &self,
280        alias_ty: ty::AliasTy<'tcx>,
281    ) -> impl Iterator<Item = ty::Region<'tcx>> {
282        let tcx = self.tcx;
283        let bounds = tcx.item_self_bounds(alias_ty.def_id);
284        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/outlives/verify.rs:284",
                        "rustc_infer::infer::outlives::verify",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/outlives/verify.rs"),
                        ::tracing_core::__macro_support::Option::Some(284u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::outlives::verify"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("{0:#?}",
                                                    bounds.skip_binder()) as &dyn Value))])
            });
    } else { ; }
};trace!("{:#?}", bounds.skip_binder());
285        bounds
286            .iter_instantiated(tcx, alias_ty.args)
287            .filter_map(|p| p.as_type_outlives_clause())
288            .filter_map(|p| p.no_bound_vars())
289            .map(|OutlivesPredicate(_, r)| r)
290    }
291}