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