Skip to main content

rustc_infer/infer/relate/
higher_ranked.rs

1//! Helper routines for higher-ranked things. See the `doc` module at
2//! the end of the file for details.
3
4use rustc_middle::ty::{self, FnMutDelegate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
5use tracing::{debug, instrument};
6
7use super::RelateResult;
8use crate::infer::InferCtxt;
9use crate::infer::snapshot::CombinedSnapshot;
10
11impl<'tcx> InferCtxt<'tcx> {
12    /// Replaces all bound variables (lifetimes, types, and constants) bound by
13    /// `binder` with placeholder variables in a new universe. This means that the
14    /// new placeholders can only be named by inference variables created after
15    /// this method has been called.
16    ///
17    /// This is the first step of checking subtyping when higher-ranked things are involved.
18    /// For more details visit the relevant sections of the [rustc dev guide].
19    ///
20    /// `fn enter_forall` should be preferred over this method.
21    ///
22    /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
23    {}
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("enter_forall_and_leak_universe",
                                "rustc_infer::infer::relate::higher_ranked",
                                ::tracing::Level::DEBUG,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs"),
                                ::tracing_core::__macro_support::Option::Some(23u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::higher_ranked"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("binder")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("binder");
                                                    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::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};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&binder)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[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: T = loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        if !binder.as_ref().skip_binder().has_escaping_bound_vars()
                            {
                            return binder.skip_binder();
                        }
                        let next_universe = self.create_next_universe();
                        let delegate =
                            FnMutDelegate {
                                regions: &mut |br: ty::BoundRegion<'tcx>|
                                        {
                                            ty::Region::new_placeholder(self.tcx,
                                                ty::PlaceholderRegion::new(next_universe, br))
                                        },
                                types: &mut |bound_ty: ty::BoundTy<'tcx>|
                                        {
                                            Ty::new_placeholder(self.tcx,
                                                ty::PlaceholderType::new(next_universe, bound_ty))
                                        },
                                consts: &mut |bound_const: ty::BoundConst<'tcx>|
                                        {
                                            ty::Const::new_placeholder(self.tcx,
                                                ty::PlaceholderConst::new(next_universe, bound_const))
                                        },
                            };
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event /rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs:50",
                                                "rustc_infer::infer::relate::higher_ranked",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs"),
                                                ::tracing_core::__macro_support::Option::Some(50u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::higher_ranked"),
                                                ::tracing_core::field::FieldSet::new(&[{
                                                                    const NAME:
                                                                        ::tracing::__macro_support::FieldName<{
                                                                            ::tracing::__macro_support::FieldName::len("next_universe")
                                                                        }> =
                                                                        ::tracing::__macro_support::FieldName::new("next_universe");
                                                                    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(&::tracing::field::debug(&next_universe)
                                                                    as &dyn ::tracing::field::Value))])
                                    });
                            } else { ; }
                        };
                        self.tcx.replace_bound_vars_uncached(binder, delegate)
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs:23",
                        "rustc_infer::infer::relate::higher_ranked",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs"),
                        ::tracing_core::__macro_support::Option::Some(23u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::higher_ranked"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            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(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(level = "debug", skip(self), ret)]
24    pub fn enter_forall_and_leak_universe<T>(&self, binder: ty::Binder<'tcx, T>) -> T
25    where
26        T: TypeFoldable<TyCtxt<'tcx>>,
27    {
28        // Inlined `no_bound_vars`.
29        if !binder.as_ref().skip_binder().has_escaping_bound_vars() {
30            return binder.skip_binder();
31        }
32
33        let next_universe = self.create_next_universe();
34
35        let delegate = FnMutDelegate {
36            regions: &mut |br: ty::BoundRegion<'tcx>| {
37                ty::Region::new_placeholder(self.tcx, ty::PlaceholderRegion::new(next_universe, br))
38            },
39            types: &mut |bound_ty: ty::BoundTy<'tcx>| {
40                Ty::new_placeholder(self.tcx, ty::PlaceholderType::new(next_universe, bound_ty))
41            },
42            consts: &mut |bound_const: ty::BoundConst<'tcx>| {
43                ty::Const::new_placeholder(
44                    self.tcx,
45                    ty::PlaceholderConst::new(next_universe, bound_const),
46                )
47            },
48        };
49
50        debug!(?next_universe);
51        self.tcx.replace_bound_vars_uncached(binder, delegate)
52    }
53
54    /// Replaces all bound variables (lifetimes, types, and constants) bound by
55    /// `binder` with placeholder variables in a new universe and then calls the
56    /// closure `f` with the instantiated value. The new placeholders can only be
57    /// named by inference variables created inside of the closure `f` or afterwards.
58    ///
59    /// This is the first step of checking subtyping when higher-ranked things are involved.
60    /// For more details visit the relevant sections of the [rustc dev guide].
61    ///
62    /// This method should be preferred over `fn enter_forall_and_leak_universe`.
63    ///
64    /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
65    {}
#[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("enter_forall",
                                    "rustc_infer::infer::relate::higher_ranked",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs"),
                                    ::tracing_core::__macro_support::Option::Some(65u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::higher_ranked"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("forall")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("forall");
                                                        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::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};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&forall)
                                                            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: U = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let value = self.enter_forall_and_leak_universe(forall);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs:75",
                                    "rustc_infer::infer::relate::higher_ranked",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/a36d05efab632d1ddf902b6a5c33b6d5d3b64131/compiler/rustc_infer/src/infer/relate/higher_ranked.rs"),
                                    ::tracing_core::__macro_support::Option::Some(75u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::higher_ranked"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("value")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("value");
                                                        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(&::tracing::field::debug(&value)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            f(value)
        }
    }
}#[instrument(level = "debug", skip(self, f))]
66    pub fn enter_forall<T, U>(&self, forall: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U) -> U
67    where
68        T: TypeFoldable<TyCtxt<'tcx>>,
69    {
70        // FIXME: currently we do nothing to prevent placeholders with the new universe being
71        // used after exiting `f`. For example region subtyping can result in outlives constraints
72        // that name placeholders created in this function. Nested goals from type relations can
73        // also contain placeholders created by this function.
74        let value = self.enter_forall_and_leak_universe(forall);
75        debug!(?value);
76        f(value)
77    }
78
79    /// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
80    /// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
81    /// universe.
82    ///
83    /// [1]: crate::infer::region_constraints::RegionConstraintCollector::leak_check
84    pub fn leak_check(
85        &self,
86        outer_universe: ty::UniverseIndex,
87        only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
88    ) -> RelateResult<'tcx, ()> {
89        // If the user gave `-Zno-leak-check`, or we have been
90        // configured to skip the leak check, then skip the leak check
91        // completely. The leak check is deprecated. Any legitimate
92        // subtyping errors that it would have caught will now be
93        // caught later on, during region checking. However, we
94        // continue to use it for a transition period.
95        if self.tcx.sess.opts.unstable_opts.no_leak_check || self.skip_leak_check {
96            return Ok(());
97        }
98
99        self.inner.borrow_mut().unwrap_region_constraints().leak_check(
100            self.tcx,
101            outer_universe,
102            self.universe(),
103            only_consider_snapshot,
104        )
105    }
106}