1use tracing::{debug, instrument};
2
3use crate::data_structures::HashSet;
4use crate::inherent::*;
5use crate::visit::TypeVisitableExt;
6use crate::{
7 ConstKind, InferCtxtLike, InferTy, Interner, Region, RegionKind, TyKind, TypeFoldable,
8 TypeSuperVisitable, TypeVisitable, TypeVisitor, UniverseIndex,
9};
10
11pub fn max_universe<Infcx: InferCtxtLike<Interner = I>, I: Interner, T: TypeFoldable<I>>(
13 infcx: &Infcx,
14 t: T,
15) -> UniverseIndex {
16 max_universe_inner::<_, _, _, true, true>(infcx, t)
17}
18
19pub fn max_universe_of_infer_vars<
21 Infcx: InferCtxtLike<Interner = I>,
22 I: Interner,
23 T: TypeFoldable<I>,
24>(
25 infcx: &Infcx,
26 t: T,
27) -> UniverseIndex {
28 max_universe_inner::<_, _, _, false, true>(infcx, t)
29}
30
31pub fn max_universe_of_placeholders<
33 Infcx: InferCtxtLike<Interner = I>,
34 I: Interner,
35 T: TypeFoldable<I>,
36>(
37 infcx: &Infcx,
38 t: T,
39) -> UniverseIndex {
40 max_universe_inner::<_, _, _, true, false>(infcx, t)
41}
42
43fn max_universe_inner<
44 Infcx: InferCtxtLike<Interner = I>,
45 I: Interner,
46 T: TypeFoldable<I>,
47 const VISIT_PLACEHOLDER: bool,
48 const VISIT_INFER: bool,
49>(
50 infcx: &Infcx,
51 t: T,
52) -> UniverseIndex {
53 if !MaxUniverse::<Infcx, I, VISIT_PLACEHOLDER, VISIT_INFER>::needs_visit(&t) {
54 return UniverseIndex::ROOT;
55 }
56
57 let mut visitor = MaxUniverse::<_, _, VISIT_PLACEHOLDER, VISIT_INFER>::new(infcx);
58 let t = infcx.resolve_vars_if_possible(t);
61 t.visit_with(&mut visitor);
62 visitor.max_universe()
63}
64
65struct MaxUniverse<
66 'a,
67 Infcx: InferCtxtLike<Interner = I>,
68 I: Interner,
69 const VISIT_PLACEHOLDER: bool,
70 const VISIT_INFER: bool,
71> {
72 max_universe: UniverseIndex,
73 infcx: &'a Infcx,
74 cache: HashSet<I::Ty>,
75}
76
77impl<
78 'a,
79 Infcx: InferCtxtLike<Interner = I>,
80 I: Interner,
81 const VISIT_PLACEHOLDER: bool,
82 const VISIT_INFER: bool,
83> MaxUniverse<'a, Infcx, I, VISIT_PLACEHOLDER, VISIT_INFER>
84{
85 fn new(infcx: &'a Infcx) -> Self {
86 MaxUniverse { infcx, max_universe: UniverseIndex::ROOT, cache: Default::default() }
87 }
88
89 fn max_universe(self) -> UniverseIndex {
90 self.max_universe
91 }
92
93 x;#[instrument(ret, level = "debug")]
94 fn needs_visit<T: TypeVisitable<I>>(t: &T) -> bool {
95 (VISIT_PLACEHOLDER && t.has_placeholders()) || (VISIT_INFER && t.has_infer())
96 }
97}
98
99impl<
100 'a,
101 Infcx: InferCtxtLike<Interner = I>,
102 I: Interner,
103 const VISIT_PLACEHOLDER: bool,
104 const VISIT_INFER: bool,
105> TypeVisitor<I> for MaxUniverse<'a, Infcx, I, VISIT_PLACEHOLDER, VISIT_INFER>
106{
107 type Result = ();
108
109 fn visit_ty(&mut self, t: I::Ty) {
110 if !Self::needs_visit(&t) {
111 return;
112 }
113
114 if self.cache.contains(&t) {
115 return;
116 }
117
118 match t.kind() {
119 TyKind::Placeholder(p) if VISIT_PLACEHOLDER => {
120 self.max_universe = self.max_universe.max(p.universe)
121 }
122 TyKind::Infer(InferTy::TyVar(inf)) if VISIT_INFER => {
123 let u = self.infcx.universe_of_ty(inf).unwrap();
124 {
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:124",
"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(124u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("var {0:?} in universe {1:?}",
inf, u) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("var {inf:?} in universe {u:?}");
125 self.max_universe = self.max_universe.max(u);
126 }
127 _ => t.super_visit_with(self),
128 }
129
130 if !self.cache.insert(t) {
{
::core::panicking::panic_fmt(format_args!("we shouldn\'t visit {0:?} twice",
t));
}
};assert!(self.cache.insert(t), "we shouldn't visit {t:?} twice");
131 }
132
133 fn visit_const(&mut self, c: I::Const) {
134 if !Self::needs_visit(&c) {
135 return;
136 }
137
138 match c.kind() {
139 ConstKind::Placeholder(p) if VISIT_PLACEHOLDER => {
140 self.max_universe = self.max_universe.max(p.universe)
141 }
142 ConstKind::Infer(rustc_type_ir::InferConst::Var(inf)) if VISIT_INFER => {
143 let u = self.infcx.universe_of_ct(inf).unwrap();
144 {
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:144",
"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(144u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("var {0:?} in universe {1:?}",
inf, u) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("var {inf:?} in universe {u:?}");
145 self.max_universe = self.max_universe.max(u);
146 }
147 _ => c.super_visit_with(self),
148 }
149 }
150
151 fn visit_region(&mut self, r: Region<I>) {
152 match r.kind() {
153 RegionKind::RePlaceholder(p) if VISIT_PLACEHOLDER => {
154 self.max_universe = self.max_universe.max(p.universe)
155 }
156 RegionKind::ReVar(var) if VISIT_INFER => {
157 match self.infcx.opportunistic_resolve_lt_var(var).kind() {
158 RegionKind::RePlaceholder(p) if VISIT_PLACEHOLDER => {
159 self.max_universe = self.max_universe.max(p.universe)
160 }
161 RegionKind::ReVar(var) if VISIT_INFER => {
162 let u = self.infcx.universe_of_lt(var).unwrap();
163 {
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:163",
"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(163u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("var {0:?} in universe {1:?}",
var, u) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("var {var:?} in universe {u:?}");
164 self.max_universe = self.max_universe.max(u);
165 }
166 _ => (),
167 }
168 }
169 _ => (),
170 }
171 }
172}