]>
Commit | Line | Data |
---|---|---|
ba9703b0 | 1 | use crate::ty::subst::{GenericArg, GenericArgKind}; |
f2b60f7d | 2 | use crate::ty::{self, InferConst, Ty, TypeFlags}; |
f035d41b | 3 | use std::slice; |
e9174d1e | 4 | |
c30ab7b3 | 5 | #[derive(Debug)] |
e9174d1e SL |
6 | pub struct FlagComputation { |
7 | pub flags: TypeFlags, | |
8 | ||
487cf647 | 9 | /// see `Ty::outer_exclusive_binder` for details |
94b46f34 | 10 | pub outer_exclusive_binder: ty::DebruijnIndex, |
e9174d1e SL |
11 | } |
12 | ||
13 | impl FlagComputation { | |
14 | fn new() -> FlagComputation { | |
dfeec247 | 15 | FlagComputation { flags: TypeFlags::empty(), outer_exclusive_binder: ty::INNERMOST } |
e9174d1e SL |
16 | } |
17 | ||
e1599b0c | 18 | #[allow(rustc::usage_of_ty_tykind)] |
e74abb32 | 19 | pub fn for_kind(kind: &ty::TyKind<'_>) -> FlagComputation { |
e9174d1e | 20 | let mut result = FlagComputation::new(); |
e74abb32 | 21 | result.add_kind(kind); |
e9174d1e SL |
22 | result |
23 | } | |
24 | ||
9c376795 | 25 | pub fn for_predicate(binder: ty::Binder<'_, ty::PredicateKind<'_>>) -> FlagComputation { |
f035d41b | 26 | let mut result = FlagComputation::new(); |
5869c6ff | 27 | result.add_predicate(binder); |
f035d41b XL |
28 | result |
29 | } | |
30 | ||
5099ac24 | 31 | pub fn for_const(c: ty::Const<'_>) -> TypeFlags { |
532ac7d7 XL |
32 | let mut result = FlagComputation::new(); |
33 | result.add_const(c); | |
34 | result.flags | |
35 | } | |
36 | ||
e9174d1e | 37 | fn add_flags(&mut self, flags: TypeFlags) { |
ba9703b0 | 38 | self.flags = self.flags | flags; |
e9174d1e SL |
39 | } |
40 | ||
94b46f34 | 41 | /// indicates that `self` refers to something at binding level `binder` |
f035d41b | 42 | fn add_bound_var(&mut self, binder: ty::DebruijnIndex) { |
94b46f34 XL |
43 | let exclusive_binder = binder.shifted_in(1); |
44 | self.add_exclusive_binder(exclusive_binder); | |
45 | } | |
46 | ||
47 | /// indicates that `self` refers to something *inside* binding | |
48 | /// level `binder` -- not bound by `binder`, but bound by the next | |
49 | /// binder internal to it | |
50 | fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) { | |
51 | self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder); | |
e9174d1e SL |
52 | } |
53 | ||
54 | /// Adds the flags/depth from a set of types that appear within the current type, but within a | |
55 | /// region binder. | |
cdc7bbd5 | 56 | fn bound_computation<T, F>(&mut self, value: ty::Binder<'_, T>, f: F) |
29967ef6 XL |
57 | where |
58 | F: FnOnce(&mut Self, T), | |
59 | { | |
60 | let mut computation = FlagComputation::new(); | |
61 | ||
9c376795 FG |
62 | for bv in value.bound_vars() { |
63 | match bv { | |
64 | ty::BoundVariableKind::Ty(_) => { | |
65 | computation.flags |= TypeFlags::HAS_TY_LATE_BOUND; | |
66 | } | |
67 | ty::BoundVariableKind::Region(_) => { | |
68 | computation.flags |= TypeFlags::HAS_RE_LATE_BOUND; | |
69 | } | |
70 | ty::BoundVariableKind::Const => { | |
71 | computation.flags |= TypeFlags::HAS_CT_LATE_BOUND; | |
72 | } | |
73 | } | |
cdc7bbd5 XL |
74 | } |
75 | ||
29967ef6 XL |
76 | f(&mut computation, value.skip_binder()); |
77 | ||
e9174d1e SL |
78 | self.add_flags(computation.flags); |
79 | ||
80 | // The types that contributed to `computation` occurred within | |
81 | // a region binder, so subtract one from the region depth | |
82 | // within when adding the depth to `self`. | |
94b46f34 XL |
83 | let outer_exclusive_binder = computation.outer_exclusive_binder; |
84 | if outer_exclusive_binder > ty::INNERMOST { | |
85 | self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1)); | |
0bf4aa26 | 86 | } // otherwise, this binder captures nothing |
e9174d1e SL |
87 | } |
88 | ||
e1599b0c | 89 | #[allow(rustc::usage_of_ty_tykind)] |
e74abb32 XL |
90 | fn add_kind(&mut self, kind: &ty::TyKind<'_>) { |
91 | match kind { | |
dfeec247 XL |
92 | &ty::Bool |
93 | | &ty::Char | |
94 | | &ty::Int(_) | |
95 | | &ty::Float(_) | |
96 | | &ty::Uint(_) | |
97 | | &ty::Never | |
98 | | &ty::Str | |
99 | | &ty::Foreign(..) => {} | |
b7449926 | 100 | |
f035d41b | 101 | &ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), |
e9174d1e | 102 | |
e1599b0c | 103 | &ty::Param(_) => { |
5099ac24 | 104 | self.add_flags(TypeFlags::HAS_TY_PARAM); |
ba9703b0 | 105 | self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); |
e9174d1e SL |
106 | } |
107 | ||
9c376795 | 108 | ty::Generator(_, substs, _) => { |
3dfed10e XL |
109 | let substs = substs.as_generator(); |
110 | let should_remove_further_specializable = | |
111 | !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); | |
112 | self.add_substs(substs.parent_substs()); | |
113 | if should_remove_further_specializable { | |
114 | self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; | |
115 | } | |
116 | ||
117 | self.add_ty(substs.resume_ty()); | |
118 | self.add_ty(substs.return_ty()); | |
119 | self.add_ty(substs.witness()); | |
120 | self.add_ty(substs.yield_ty()); | |
121 | self.add_ty(substs.tupled_upvars_ty()); | |
ea8adc8c XL |
122 | } |
123 | ||
f035d41b | 124 | &ty::GeneratorWitness(ts) => { |
29967ef6 | 125 | self.bound_computation(ts, |flags, ts| flags.add_tys(ts)); |
2c00a5a8 XL |
126 | } |
127 | ||
9ffffee4 FG |
128 | ty::GeneratorWitnessMIR(_, substs) => { |
129 | let should_remove_further_specializable = | |
130 | !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); | |
131 | self.add_substs(substs); | |
132 | if should_remove_further_specializable { | |
133 | self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; | |
134 | } | |
135 | self.add_flags(TypeFlags::HAS_TY_GENERATOR); | |
136 | } | |
137 | ||
f035d41b | 138 | &ty::Closure(_, substs) => { |
3dfed10e XL |
139 | let substs = substs.as_closure(); |
140 | let should_remove_further_specializable = | |
141 | !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); | |
142 | self.add_substs(substs.parent_substs()); | |
143 | if should_remove_further_specializable { | |
144 | self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; | |
145 | } | |
146 | ||
147 | self.add_ty(substs.sig_as_fn_ptr_ty()); | |
148 | self.add_ty(substs.kind_ty()); | |
149 | self.add_ty(substs.tupled_upvars_ty()); | |
e9174d1e SL |
150 | } |
151 | ||
a1dfa0c6 | 152 | &ty::Bound(debruijn, _) => { |
f035d41b | 153 | self.add_bound_var(debruijn); |
9c376795 | 154 | self.add_flags(TypeFlags::HAS_TY_LATE_BOUND); |
a1dfa0c6 XL |
155 | } |
156 | ||
157 | &ty::Placeholder(..) => { | |
158 | self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER); | |
ba9703b0 | 159 | self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); |
a1dfa0c6 XL |
160 | } |
161 | ||
b7449926 | 162 | &ty::Infer(infer) => { |
ba9703b0 | 163 | self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); |
a7813a04 | 164 | match infer { |
17df50a5 XL |
165 | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { |
166 | self.add_flags(TypeFlags::HAS_TY_FRESH) | |
167 | } | |
0531ce1d | 168 | |
dfeec247 | 169 | ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => { |
ba9703b0 | 170 | self.add_flags(TypeFlags::HAS_TY_INFER) |
0531ce1d | 171 | } |
a7813a04 | 172 | } |
e9174d1e SL |
173 | } |
174 | ||
b7449926 | 175 | &ty::Adt(_, substs) => { |
e9174d1e SL |
176 | self.add_substs(substs); |
177 | } | |
178 | ||
9c376795 | 179 | &ty::Alias(ty::Projection, data) => { |
74b04a01 | 180 | self.add_flags(TypeFlags::HAS_TY_PROJECTION); |
e9174d1e SL |
181 | self.add_projection_ty(data); |
182 | } | |
183 | ||
9c376795 | 184 | &ty::Alias(ty::Opaque, ty::AliasTy { substs, .. }) => { |
74b04a01 | 185 | self.add_flags(TypeFlags::HAS_TY_OPAQUE); |
5bcae85e SL |
186 | self.add_substs(substs); |
187 | } | |
188 | ||
f2b60f7d | 189 | &ty::Dynamic(obj, r, _) => { |
fc512014 XL |
190 | for predicate in obj.iter() { |
191 | self.bound_computation(predicate, |computation, predicate| match predicate { | |
192 | ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs), | |
193 | ty::ExistentialPredicate::Projection(p) => { | |
194 | computation.add_existential_projection(&p); | |
476ff2be | 195 | } |
fc512014 XL |
196 | ty::ExistentialPredicate::AutoTrait(_) => {} |
197 | }); | |
198 | } | |
29967ef6 | 199 | |
476ff2be | 200 | self.add_region(r); |
e9174d1e SL |
201 | } |
202 | ||
b7449926 | 203 | &ty::Array(tt, len) => { |
ea8adc8c | 204 | self.add_ty(tt); |
532ac7d7 | 205 | self.add_const(len); |
ea8adc8c XL |
206 | } |
207 | ||
dfeec247 | 208 | &ty::Slice(tt) => self.add_ty(tt), |
e9174d1e | 209 | |
9c376795 | 210 | ty::RawPtr(m) => { |
e9174d1e SL |
211 | self.add_ty(m.ty); |
212 | } | |
213 | ||
b7449926 | 214 | &ty::Ref(r, ty, _) => { |
9e0c209e | 215 | self.add_region(r); |
94b46f34 | 216 | self.add_ty(ty); |
e9174d1e SL |
217 | } |
218 | ||
5e7ed085 FG |
219 | &ty::Tuple(types) => { |
220 | self.add_tys(types); | |
e9174d1e SL |
221 | } |
222 | ||
b7449926 | 223 | &ty::FnDef(_, substs) => { |
54a0048b | 224 | self.add_substs(substs); |
54a0048b SL |
225 | } |
226 | ||
29967ef6 XL |
227 | &ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| { |
228 | computation.add_tys(fn_sig.inputs()); | |
229 | computation.add_ty(fn_sig.output()); | |
230 | }), | |
e9174d1e SL |
231 | } |
232 | } | |
233 | ||
a2a8927a | 234 | fn add_predicate(&mut self, binder: ty::Binder<'_, ty::PredicateKind<'_>>) { |
5869c6ff | 235 | self.bound_computation(binder, |computation, atom| computation.add_predicate_atom(atom)); |
3dfed10e | 236 | } |
f035d41b | 237 | |
5869c6ff | 238 | fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) { |
3dfed10e | 239 | match atom { |
487cf647 | 240 | ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => { |
3dfed10e | 241 | self.add_substs(trait_pred.trait_ref.substs); |
f035d41b | 242 | } |
487cf647 | 243 | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate(a, b))) => { |
3dfed10e XL |
244 | self.add_region(a); |
245 | self.add_region(b); | |
f035d41b | 246 | } |
487cf647 FG |
247 | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( |
248 | ty, | |
249 | region, | |
250 | ))) => { | |
3dfed10e XL |
251 | self.add_ty(ty); |
252 | self.add_region(region); | |
253 | } | |
9ffffee4 FG |
254 | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { |
255 | self.add_const(ct); | |
256 | self.add_ty(ty); | |
257 | } | |
5869c6ff | 258 | ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => { |
3dfed10e XL |
259 | self.add_ty(a); |
260 | self.add_ty(b); | |
261 | } | |
94222f64 XL |
262 | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { |
263 | self.add_ty(a); | |
264 | self.add_ty(b); | |
265 | } | |
487cf647 FG |
266 | ty::PredicateKind::Clause(ty::Clause::Projection(ty::ProjectionPredicate { |
267 | projection_ty, | |
268 | term, | |
269 | })) => { | |
3dfed10e | 270 | self.add_projection_ty(projection_ty); |
9ffffee4 | 271 | self.add_term(term); |
f035d41b | 272 | } |
5869c6ff | 273 | ty::PredicateKind::WellFormed(arg) => { |
3dfed10e | 274 | self.add_substs(slice::from_ref(&arg)); |
f035d41b | 275 | } |
5869c6ff XL |
276 | ty::PredicateKind::ObjectSafe(_def_id) => {} |
277 | ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => { | |
f035d41b XL |
278 | self.add_substs(substs); |
279 | } | |
94222f64 | 280 | ty::PredicateKind::ConstEvaluatable(uv) => { |
2b03887a | 281 | self.add_const(uv); |
f035d41b | 282 | } |
5869c6ff | 283 | ty::PredicateKind::ConstEquate(expected, found) => { |
f035d41b XL |
284 | self.add_const(expected); |
285 | self.add_const(found); | |
286 | } | |
5869c6ff | 287 | ty::PredicateKind::TypeWellFormedFromEnv(ty) => { |
1b1a35ee XL |
288 | self.add_ty(ty); |
289 | } | |
487cf647 | 290 | ty::PredicateKind::Ambiguous => {} |
353b0b11 | 291 | ty::PredicateKind::AliasRelate(t1, t2, _) => { |
9ffffee4 FG |
292 | self.add_term(t1); |
293 | self.add_term(t2); | |
294 | } | |
f035d41b XL |
295 | } |
296 | } | |
297 | ||
0bf4aa26 | 298 | fn add_ty(&mut self, ty: Ty<'_>) { |
1b1a35ee | 299 | self.add_flags(ty.flags()); |
5099ac24 | 300 | self.add_exclusive_binder(ty.outer_exclusive_binder()); |
e9174d1e SL |
301 | } |
302 | ||
0bf4aa26 | 303 | fn add_tys(&mut self, tys: &[Ty<'_>]) { |
e9174d1e SL |
304 | for &ty in tys { |
305 | self.add_ty(ty); | |
306 | } | |
307 | } | |
308 | ||
0bf4aa26 | 309 | fn add_region(&mut self, r: ty::Region<'_>) { |
c30ab7b3 SL |
310 | self.add_flags(r.type_flags()); |
311 | if let ty::ReLateBound(debruijn, _) = *r { | |
f035d41b | 312 | self.add_bound_var(debruijn); |
e9174d1e SL |
313 | } |
314 | } | |
315 | ||
5099ac24 FG |
316 | fn add_const(&mut self, c: ty::Const<'_>) { |
317 | self.add_ty(c.ty()); | |
923072b8 | 318 | match c.kind() { |
2b03887a FG |
319 | ty::ConstKind::Unevaluated(uv) => { |
320 | self.add_substs(uv.substs); | |
321 | self.add_flags(TypeFlags::HAS_CT_PROJECTION); | |
322 | } | |
60c5eb7d | 323 | ty::ConstKind::Infer(infer) => { |
ba9703b0 | 324 | self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); |
532ac7d7 | 325 | match infer { |
17df50a5 | 326 | InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH), |
ba9703b0 | 327 | InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER), |
532ac7d7 XL |
328 | } |
329 | } | |
ba9703b0 | 330 | ty::ConstKind::Bound(debruijn, _) => { |
f035d41b | 331 | self.add_bound_var(debruijn); |
9c376795 | 332 | self.add_flags(TypeFlags::HAS_CT_LATE_BOUND); |
ba9703b0 | 333 | } |
60c5eb7d | 334 | ty::ConstKind::Param(_) => { |
5099ac24 | 335 | self.add_flags(TypeFlags::HAS_CT_PARAM); |
ba9703b0 | 336 | self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); |
532ac7d7 | 337 | } |
60c5eb7d | 338 | ty::ConstKind::Placeholder(_) => { |
e74abb32 | 339 | self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); |
ba9703b0 | 340 | self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); |
48663c56 | 341 | } |
60c5eb7d | 342 | ty::ConstKind::Value(_) => {} |
487cf647 FG |
343 | ty::ConstKind::Expr(e) => { |
344 | use ty::Expr; | |
345 | match e { | |
346 | Expr::Binop(_, l, r) => { | |
347 | self.add_const(l); | |
348 | self.add_const(r); | |
349 | } | |
350 | Expr::UnOp(_, v) => self.add_const(v), | |
351 | Expr::FunctionCall(f, args) => { | |
352 | self.add_const(f); | |
353 | for arg in args { | |
354 | self.add_const(arg); | |
355 | } | |
356 | } | |
357 | Expr::Cast(_, c, t) => { | |
358 | self.add_ty(t); | |
359 | self.add_const(c); | |
360 | } | |
361 | } | |
362 | } | |
f035d41b | 363 | ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), |
532ac7d7 XL |
364 | } |
365 | } | |
366 | ||
0bf4aa26 | 367 | fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) { |
041b39d2 | 368 | self.add_substs(projection.substs); |
f2b60f7d FG |
369 | match projection.term.unpack() { |
370 | ty::TermKind::Ty(ty) => self.add_ty(ty), | |
371 | ty::TermKind::Const(ct) => self.add_const(ct), | |
5099ac24 | 372 | } |
e9174d1e SL |
373 | } |
374 | ||
9c376795 | 375 | fn add_projection_ty(&mut self, projection_ty: ty::AliasTy<'_>) { |
041b39d2 | 376 | self.add_substs(projection_ty.substs); |
e9174d1e SL |
377 | } |
378 | ||
ba9703b0 | 379 | fn add_substs(&mut self, substs: &[GenericArg<'_>]) { |
532ac7d7 XL |
380 | for kind in substs { |
381 | match kind.unpack() { | |
e74abb32 XL |
382 | GenericArgKind::Type(ty) => self.add_ty(ty), |
383 | GenericArgKind::Lifetime(lt) => self.add_region(lt), | |
384 | GenericArgKind::Const(ct) => self.add_const(ct), | |
532ac7d7 | 385 | } |
9e0c209e | 386 | } |
e9174d1e | 387 | } |
9ffffee4 FG |
388 | |
389 | fn add_term(&mut self, term: ty::Term<'_>) { | |
390 | match term.unpack() { | |
391 | ty::TermKind::Ty(ty) => self.add_ty(ty), | |
392 | ty::TermKind::Const(ct) => self.add_const(ct), | |
393 | } | |
394 | } | |
e9174d1e | 395 | } |