Skip to main content

rustc_type_ir/
universe.rs

1use tracing::{debug, instrument};
2
3use crate::inherent::*;
4use crate::visit::TypeVisitableExt;
5use crate::{
6    ConstKind, InferCtxtLike, InferTy, Interner, RegionKind, TyKind, TypeFoldable,
7    TypeSuperVisitable, TypeVisitable, TypeVisitor, UniverseIndex,
8};
9
10/// The largest universe a variable or placeholder was from in `t`
11pub fn max_universe<Infcx: InferCtxtLike<Interner = I>, I: Interner, T: TypeFoldable<I>>(
12    infcx: &Infcx,
13    t: T,
14) -> UniverseIndex {
15    max_universe_inner::<_, _, _, true, true>(infcx, t)
16}
17
18/// The largest universe a variable was from in `t`
19pub fn max_universe_of_infer_vars<
20    Infcx: InferCtxtLike<Interner = I>,
21    I: Interner,
22    T: TypeFoldable<I>,
23>(
24    infcx: &Infcx,
25    t: T,
26) -> UniverseIndex {
27    max_universe_inner::<_, _, _, false, true>(infcx, t)
28}
29
30/// The largest universe a placeholder was from in `t`
31pub fn max_universe_of_placeholders<
32    Infcx: InferCtxtLike<Interner = I>,
33    I: Interner,
34    T: TypeFoldable<I>,
35>(
36    infcx: &Infcx,
37    t: T,
38) -> UniverseIndex {
39    max_universe_inner::<_, _, _, true, false>(infcx, t)
40}
41
42fn max_universe_inner<
43    Infcx: InferCtxtLike<Interner = I>,
44    I: Interner,
45    T: TypeFoldable<I>,
46    const VISIT_PLACEHOLDER: bool,
47    const VISIT_INFER: bool,
48>(
49    infcx: &Infcx,
50    t: T,
51) -> UniverseIndex {
52    if !MaxUniverse::<Infcx, VISIT_PLACEHOLDER, VISIT_INFER>::needs_visit(&t) {
53        return UniverseIndex::ROOT;
54    }
55
56    let mut visitor = MaxUniverse::<_, VISIT_PLACEHOLDER, VISIT_INFER>::new(infcx);
57    // FIXME: make this a debug_assert and let callers resolve vars if there's
58    // perf win here.
59    let t = infcx.resolve_vars_if_possible(t);
60    t.visit_with(&mut visitor);
61    visitor.max_universe()
62}
63
64struct MaxUniverse<'a, Infcx: InferCtxtLike, const VISIT_PLACEHOLDER: bool, const VISIT_INFER: bool>
65{
66    max_universe: UniverseIndex,
67    infcx: &'a Infcx,
68}
69
70impl<'a, Infcx: InferCtxtLike, const VISIT_PLACEHOLDER: bool, const VISIT_INFER: bool>
71    MaxUniverse<'a, Infcx, VISIT_PLACEHOLDER, VISIT_INFER>
72{
73    fn new(infcx: &'a Infcx) -> Self {
74        MaxUniverse { infcx, max_universe: UniverseIndex::ROOT }
75    }
76
77    fn max_universe(self) -> UniverseIndex {
78        self.max_universe
79    }
80
81    x;#[instrument(ret, level = "debug")]
82    fn needs_visit<T: TypeVisitable<I>, I: Interner>(t: &T) -> bool {
83        (VISIT_PLACEHOLDER && t.has_placeholders()) || (VISIT_INFER && t.has_infer())
84    }
85}
86
87impl<
88    'a,
89    Infcx: InferCtxtLike<Interner = I>,
90    I: Interner,
91    const VISIT_PLACEHOLDER: bool,
92    const VISIT_INFER: bool,
93> TypeVisitor<I> for MaxUniverse<'a, Infcx, VISIT_PLACEHOLDER, VISIT_INFER>
94{
95    type Result = ();
96
97    fn visit_ty(&mut self, t: I::Ty) {
98        if !Self::needs_visit(&t) {
99            return;
100        }
101
102        match t.kind() {
103            TyKind::Placeholder(p) if VISIT_PLACEHOLDER => {
104                self.max_universe = self.max_universe.max(p.universe)
105            }
106            TyKind::Infer(InferTy::TyVar(inf)) if VISIT_INFER => {
107                let u = self.infcx.universe_of_ty(inf).unwrap();
108                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/universe.rs:108",
                        "rustc_type_ir::universe", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/universe.rs"),
                        ::tracing_core::__macro_support::Option::Some(108u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_type_ir::universe"),
                        ::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!("var {0:?} in universe {1:?}",
                                                    inf, u) as &dyn Value))])
            });
    } else { ; }
};debug!("var {inf:?} in universe {u:?}");
109                self.max_universe = self.max_universe.max(u);
110            }
111            _ => t.super_visit_with(self),
112        }
113    }
114
115    fn visit_const(&mut self, c: I::Const) {
116        if !Self::needs_visit(&c) {
117            return;
118        }
119
120        match c.kind() {
121            ConstKind::Placeholder(p) if VISIT_PLACEHOLDER => {
122                self.max_universe = self.max_universe.max(p.universe)
123            }
124            ConstKind::Infer(rustc_type_ir::InferConst::Var(inf)) if VISIT_INFER => {
125                let u = self.infcx.universe_of_ct(inf).unwrap();
126                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/universe.rs:126",
                        "rustc_type_ir::universe", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/universe.rs"),
                        ::tracing_core::__macro_support::Option::Some(126u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_type_ir::universe"),
                        ::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!("var {0:?} in universe {1:?}",
                                                    inf, u) as &dyn Value))])
            });
    } else { ; }
};debug!("var {inf:?} in universe {u:?}");
127                self.max_universe = self.max_universe.max(u);
128            }
129            _ => c.super_visit_with(self),
130        }
131    }
132
133    fn visit_region(&mut self, r: I::Region) {
134        match r.kind() {
135            RegionKind::RePlaceholder(p) if VISIT_PLACEHOLDER => {
136                self.max_universe = self.max_universe.max(p.universe)
137            }
138            RegionKind::ReVar(var) if VISIT_INFER => {
139                match self.infcx.opportunistic_resolve_lt_var(var).kind() {
140                    RegionKind::RePlaceholder(p) if VISIT_PLACEHOLDER => {
141                        self.max_universe = self.max_universe.max(p.universe)
142                    }
143                    RegionKind::ReVar(var) if VISIT_INFER => {
144                        let u = self.infcx.universe_of_lt(var).unwrap();
145                        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/universe.rs:145",
                        "rustc_type_ir::universe", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/universe.rs"),
                        ::tracing_core::__macro_support::Option::Some(145u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_type_ir::universe"),
                        ::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!("var {0:?} in universe {1:?}",
                                                    var, u) as &dyn Value))])
            });
    } else { ; }
};debug!("var {var:?} in universe {u:?}");
146                        self.max_universe = self.max_universe.max(u);
147                    }
148                    _ => (),
149                }
150            }
151            _ => (),
152        }
153    }
154}