]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
ff7c6d11 XL |
11 | //! This module contains implements of the `Lift` and `TypeFoldable` |
12 | //! traits for various types in the Rust compiler. Most are written by | |
13 | //! hand, though we've recently added some macros (e.g., | |
14 | //! `BraceStructLiftImpl!`) to help with the tedium. | |
15 | ||
0bf4aa26 | 16 | use mir::ProjectionKind; |
8faf50e0 | 17 | use mir::interpret::{ConstValue, ConstEvalErr}; |
9e0c209e | 18 | use ty::{self, Lift, Ty, TyCtxt}; |
54a0048b | 19 | use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; |
8bb4bdeb | 20 | use rustc_data_structures::indexed_vec::{IndexVec, Idx}; |
b7449926 | 21 | use smallvec::SmallVec; |
0531ce1d | 22 | use mir::interpret; |
e9174d1e SL |
23 | |
24 | use std::rc::Rc; | |
e9174d1e | 25 | |
ff7c6d11 XL |
26 | /////////////////////////////////////////////////////////////////////////// |
27 | // Atomic structs | |
28 | // | |
29 | // For things that don't carry any arena-allocated data (and are | |
30 | // copy...), just add them to this list. | |
31 | ||
0531ce1d | 32 | CloneTypeFoldableAndLiftImpls! { |
ff7c6d11 | 33 | (), |
0531ce1d XL |
34 | bool, |
35 | usize, | |
36 | u64, | |
37 | ::middle::region::Scope, | |
38 | ::syntax::ast::FloatTy, | |
39 | ::syntax::ast::NodeId, | |
40 | ::syntax_pos::symbol::Symbol, | |
41 | ::hir::def::Def, | |
42 | ::hir::def_id::DefId, | |
43 | ::hir::InlineAsm, | |
44 | ::hir::MatchSource, | |
45 | ::hir::Mutability, | |
ff7c6d11 | 46 | ::hir::Unsafety, |
83c7162d | 47 | ::rustc_target::spec::abi::Abi, |
ff7c6d11 | 48 | ::mir::Local, |
0531ce1d | 49 | ::mir::Promoted, |
ff7c6d11 | 50 | ::traits::Reveal, |
0531ce1d XL |
51 | ::ty::adjustment::AutoBorrowMutability, |
52 | ::ty::AdtKind, | |
53 | // Including `BoundRegion` is a *bit* dubious, but direct | |
54 | // references to bound region appear in `ty::Error`, and aren't | |
55 | // really meant to be folded. In general, we can only fold a fully | |
56 | // general `Region`. | |
57 | ::ty::BoundRegion, | |
58 | ::ty::ClosureKind, | |
59 | ::ty::IntVarValue, | |
8faf50e0 | 60 | ::ty::ParamTy, |
0bf4aa26 | 61 | ::ty::UniverseIndex, |
b7449926 | 62 | ::ty::Variance, |
ff7c6d11 XL |
63 | ::syntax_pos::Span, |
64 | } | |
65 | ||
e9174d1e SL |
66 | /////////////////////////////////////////////////////////////////////////// |
67 | // Lift implementations | |
68 | ||
69 | impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) { | |
70 | type Lifted = (A::Lifted, B::Lifted); | |
a7813a04 | 71 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
e9174d1e SL |
72 | tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b))) |
73 | } | |
74 | } | |
75 | ||
ea8adc8c XL |
76 | impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) { |
77 | type Lifted = (A::Lifted, B::Lifted, C::Lifted); | |
78 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
79 | tcx.lift(&self.0).and_then(|a| { | |
80 | tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c))) | |
81 | }) | |
82 | } | |
83 | } | |
84 | ||
a7813a04 XL |
85 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> { |
86 | type Lifted = Option<T::Lifted>; | |
87 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
88 | match *self { | |
89 | Some(ref x) => tcx.lift(x).map(Some), | |
90 | None => Some(None) | |
91 | } | |
92 | } | |
93 | } | |
94 | ||
95 | impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> { | |
96 | type Lifted = Result<T::Lifted, E::Lifted>; | |
97 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
98 | match *self { | |
99 | Ok(ref x) => tcx.lift(x).map(Ok), | |
100 | Err(ref e) => tcx.lift(e).map(Err) | |
101 | } | |
102 | } | |
103 | } | |
104 | ||
ea8adc8c XL |
105 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> { |
106 | type Lifted = Box<T::Lifted>; | |
107 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
108 | tcx.lift(&**self).map(Box::new) | |
109 | } | |
110 | } | |
111 | ||
e9174d1e SL |
112 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] { |
113 | type Lifted = Vec<T::Lifted>; | |
a7813a04 | 114 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
b039eaaf SL |
115 | // type annotation needed to inform `projection_must_outlive` |
116 | let mut result : Vec<<T as Lift<'tcx>>::Lifted> | |
117 | = Vec::with_capacity(self.len()); | |
e9174d1e SL |
118 | for x in self { |
119 | if let Some(value) = tcx.lift(x) { | |
120 | result.push(value); | |
121 | } else { | |
122 | return None; | |
123 | } | |
124 | } | |
125 | Some(result) | |
126 | } | |
127 | } | |
128 | ||
a7813a04 XL |
129 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> { |
130 | type Lifted = Vec<T::Lifted>; | |
131 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
132 | tcx.lift(&self[..]) | |
133 | } | |
134 | } | |
135 | ||
ff7c6d11 XL |
136 | impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> { |
137 | type Lifted = IndexVec<I, T::Lifted>; | |
138 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
139 | self.iter() | |
140 | .map(|e| tcx.lift(e)) | |
141 | .collect() | |
142 | } | |
143 | } | |
144 | ||
9e0c209e SL |
145 | impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> { |
146 | type Lifted = ty::TraitRef<'tcx>; | |
147 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
148 | tcx.lift(&self.substs).map(|substs| ty::TraitRef { | |
149 | def_id: self.def_id, | |
041b39d2 | 150 | substs, |
9e0c209e | 151 | }) |
e9174d1e SL |
152 | } |
153 | } | |
154 | ||
9e0c209e SL |
155 | impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { |
156 | type Lifted = ty::ExistentialTraitRef<'tcx>; | |
157 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
158 | tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef { | |
e9174d1e | 159 | def_id: self.def_id, |
041b39d2 | 160 | substs, |
e9174d1e SL |
161 | }) |
162 | } | |
163 | } | |
164 | ||
165 | impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { | |
166 | type Lifted = ty::TraitPredicate<'tcx>; | |
a7813a04 XL |
167 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) |
168 | -> Option<ty::TraitPredicate<'tcx>> { | |
e9174d1e | 169 | tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate { |
041b39d2 | 170 | trait_ref, |
e9174d1e SL |
171 | }) |
172 | } | |
173 | } | |
174 | ||
cc61c64b XL |
175 | impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> { |
176 | type Lifted = ty::SubtypePredicate<'tcx>; | |
177 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) | |
178 | -> Option<ty::SubtypePredicate<'tcx>> { | |
179 | tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate { | |
180 | a_is_expected: self.a_is_expected, | |
041b39d2 XL |
181 | a, |
182 | b, | |
cc61c64b XL |
183 | }) |
184 | } | |
185 | } | |
186 | ||
e9174d1e SL |
187 | impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> { |
188 | type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>; | |
a7813a04 | 189 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
e9174d1e SL |
190 | tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b)) |
191 | } | |
192 | } | |
193 | ||
5bcae85e SL |
194 | impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> { |
195 | type Lifted = ty::ProjectionTy<'tcx>; | |
196 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) | |
197 | -> Option<ty::ProjectionTy<'tcx>> { | |
041b39d2 XL |
198 | tcx.lift(&self.substs).map(|substs| { |
199 | ty::ProjectionTy { | |
200 | item_def_id: self.item_def_id, | |
3b2f2976 | 201 | substs, |
041b39d2 | 202 | } |
5bcae85e SL |
203 | }) |
204 | } | |
205 | } | |
206 | ||
e9174d1e SL |
207 | impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> { |
208 | type Lifted = ty::ProjectionPredicate<'tcx>; | |
a7813a04 XL |
209 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) |
210 | -> Option<ty::ProjectionPredicate<'tcx>> { | |
5bcae85e | 211 | tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| { |
e9174d1e | 212 | ty::ProjectionPredicate { |
041b39d2 XL |
213 | projection_ty, |
214 | ty, | |
e9174d1e SL |
215 | } |
216 | }) | |
217 | } | |
218 | } | |
219 | ||
9e0c209e SL |
220 | impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> { |
221 | type Lifted = ty::ExistentialProjection<'tcx>; | |
222 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
041b39d2 | 223 | tcx.lift(&self.substs).map(|substs| { |
9e0c209e | 224 | ty::ExistentialProjection { |
041b39d2 XL |
225 | substs, |
226 | ty: tcx.lift(&self.ty).expect("type must lift when substs do"), | |
227 | item_def_id: self.item_def_id, | |
9e0c209e SL |
228 | } |
229 | }) | |
230 | } | |
231 | } | |
232 | ||
a7813a04 XL |
233 | impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> { |
234 | type Lifted = ty::Predicate<'tcx>; | |
235 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
236 | match *self { | |
237 | ty::Predicate::Trait(ref binder) => { | |
238 | tcx.lift(binder).map(ty::Predicate::Trait) | |
239 | } | |
cc61c64b XL |
240 | ty::Predicate::Subtype(ref binder) => { |
241 | tcx.lift(binder).map(ty::Predicate::Subtype) | |
242 | } | |
a7813a04 XL |
243 | ty::Predicate::RegionOutlives(ref binder) => { |
244 | tcx.lift(binder).map(ty::Predicate::RegionOutlives) | |
245 | } | |
246 | ty::Predicate::TypeOutlives(ref binder) => { | |
247 | tcx.lift(binder).map(ty::Predicate::TypeOutlives) | |
248 | } | |
249 | ty::Predicate::Projection(ref binder) => { | |
250 | tcx.lift(binder).map(ty::Predicate::Projection) | |
251 | } | |
252 | ty::Predicate::WellFormed(ty) => { | |
253 | tcx.lift(&ty).map(ty::Predicate::WellFormed) | |
254 | } | |
ff7c6d11 XL |
255 | ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { |
256 | tcx.lift(&closure_substs) | |
257 | .map(|closure_substs| ty::Predicate::ClosureKind(closure_def_id, | |
258 | closure_substs, | |
259 | kind)) | |
a7813a04 XL |
260 | } |
261 | ty::Predicate::ObjectSafe(trait_def_id) => { | |
262 | Some(ty::Predicate::ObjectSafe(trait_def_id)) | |
263 | } | |
ea8adc8c XL |
264 | ty::Predicate::ConstEvaluatable(def_id, substs) => { |
265 | tcx.lift(&substs).map(|substs| { | |
266 | ty::Predicate::ConstEvaluatable(def_id, substs) | |
267 | }) | |
268 | } | |
a7813a04 XL |
269 | } |
270 | } | |
271 | } | |
272 | ||
e9174d1e SL |
273 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> { |
274 | type Lifted = ty::Binder<T::Lifted>; | |
a7813a04 | 275 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
83c7162d | 276 | tcx.lift(self.skip_binder()).map(ty::Binder::bind) |
e9174d1e SL |
277 | } |
278 | } | |
279 | ||
ea8adc8c XL |
280 | impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { |
281 | type Lifted = ty::ParamEnv<'tcx>; | |
282 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
283 | tcx.lift(&self.caller_bounds).map(|caller_bounds| { | |
284 | ty::ParamEnv { | |
285 | reveal: self.reveal, | |
286 | caller_bounds, | |
287 | } | |
288 | }) | |
289 | } | |
290 | } | |
291 | ||
292 | impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> { | |
293 | type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>; | |
294 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
295 | tcx.lift(&self.param_env).and_then(|param_env| { | |
296 | tcx.lift(&self.value).map(|value| { | |
297 | ty::ParamEnvAnd { | |
298 | param_env, | |
299 | value, | |
300 | } | |
301 | }) | |
302 | }) | |
303 | } | |
304 | } | |
305 | ||
a7813a04 XL |
306 | impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> { |
307 | type Lifted = ty::ClosureSubsts<'tcx>; | |
308 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
476ff2be | 309 | tcx.lift(&self.substs).map(|substs| { |
94b46f34 | 310 | ty::ClosureSubsts { substs } |
a7813a04 XL |
311 | }) |
312 | } | |
313 | } | |
314 | ||
94b46f34 XL |
315 | impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> { |
316 | type Lifted = ty::GeneratorSubsts<'tcx>; | |
ea8adc8c | 317 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
94b46f34 XL |
318 | tcx.lift(&self.substs).map(|substs| { |
319 | ty::GeneratorSubsts { substs } | |
ea8adc8c XL |
320 | }) |
321 | } | |
322 | } | |
323 | ||
7cac9316 XL |
324 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> { |
325 | type Lifted = ty::adjustment::Adjustment<'tcx>; | |
a7813a04 | 326 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
7cac9316 XL |
327 | tcx.lift(&self.kind).and_then(|kind| { |
328 | tcx.lift(&self.target).map(|target| { | |
329 | ty::adjustment::Adjustment { kind, target } | |
330 | }) | |
331 | }) | |
332 | } | |
333 | } | |
334 | ||
335 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> { | |
336 | type Lifted = ty::adjustment::Adjust<'tcx>; | |
337 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
338 | match *self { | |
339 | ty::adjustment::Adjust::NeverToAny => | |
340 | Some(ty::adjustment::Adjust::NeverToAny), | |
341 | ty::adjustment::Adjust::ReifyFnPointer => | |
342 | Some(ty::adjustment::Adjust::ReifyFnPointer), | |
343 | ty::adjustment::Adjust::UnsafeFnPointer => | |
344 | Some(ty::adjustment::Adjust::UnsafeFnPointer), | |
345 | ty::adjustment::Adjust::ClosureFnPointer => | |
346 | Some(ty::adjustment::Adjust::ClosureFnPointer), | |
347 | ty::adjustment::Adjust::MutToConstPointer => | |
348 | Some(ty::adjustment::Adjust::MutToConstPointer), | |
349 | ty::adjustment::Adjust::Unsize => | |
350 | Some(ty::adjustment::Adjust::Unsize), | |
351 | ty::adjustment::Adjust::Deref(ref overloaded) => { | |
352 | tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref) | |
353 | } | |
354 | ty::adjustment::Adjust::Borrow(ref autoref) => { | |
355 | tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow) | |
356 | } | |
357 | } | |
358 | } | |
359 | } | |
360 | ||
361 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> { | |
362 | type Lifted = ty::adjustment::OverloadedDeref<'tcx>; | |
363 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
364 | tcx.lift(&self.region).map(|region| { | |
365 | ty::adjustment::OverloadedDeref { | |
366 | region, | |
367 | mutbl: self.mutbl, | |
a7813a04 XL |
368 | } |
369 | }) | |
370 | } | |
371 | } | |
372 | ||
c30ab7b3 SL |
373 | impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { |
374 | type Lifted = ty::adjustment::AutoBorrow<'tcx>; | |
a7813a04 XL |
375 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
376 | match *self { | |
c30ab7b3 SL |
377 | ty::adjustment::AutoBorrow::Ref(r, m) => { |
378 | tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m)) | |
a7813a04 | 379 | } |
c30ab7b3 SL |
380 | ty::adjustment::AutoBorrow::RawPtr(m) => { |
381 | Some(ty::adjustment::AutoBorrow::RawPtr(m)) | |
a7813a04 XL |
382 | } |
383 | } | |
384 | } | |
385 | } | |
386 | ||
ea8adc8c XL |
387 | impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> { |
388 | type Lifted = ty::GenSig<'tcx>; | |
389 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
390 | tcx.lift(&(self.yield_ty, self.return_ty)) | |
0bf4aa26 XL |
391 | .map(|(yield_ty, return_ty)| { |
392 | ty::GenSig { | |
393 | yield_ty, | |
394 | return_ty, | |
395 | } | |
396 | }) | |
ea8adc8c XL |
397 | } |
398 | } | |
399 | ||
a7813a04 XL |
400 | impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> { |
401 | type Lifted = ty::FnSig<'tcx>; | |
402 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
476ff2be SL |
403 | tcx.lift(&self.inputs_and_output).map(|x| { |
404 | ty::FnSig { | |
405 | inputs_and_output: x, | |
8bb4bdeb | 406 | variadic: self.variadic, |
a7813a04 | 407 | unsafety: self.unsafety, |
8bb4bdeb | 408 | abi: self.abi, |
a7813a04 XL |
409 | } |
410 | }) | |
411 | } | |
412 | } | |
413 | ||
414 | impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> { | |
415 | type Lifted = ty::error::ExpectedFound<T::Lifted>; | |
416 | fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
417 | tcx.lift(&self.expected).and_then(|expected| { | |
418 | tcx.lift(&self.found).map(|found| { | |
419 | ty::error::ExpectedFound { | |
041b39d2 XL |
420 | expected, |
421 | found, | |
a7813a04 XL |
422 | } |
423 | }) | |
424 | }) | |
425 | } | |
426 | } | |
427 | ||
a7813a04 XL |
428 | impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { |
429 | type Lifted = ty::error::TypeError<'tcx>; | |
430 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
431 | use ty::error::TypeError::*; | |
432 | ||
433 | Some(match *self { | |
434 | Mismatch => Mismatch, | |
435 | UnsafetyMismatch(x) => UnsafetyMismatch(x), | |
436 | AbiMismatch(x) => AbiMismatch(x), | |
437 | Mutability => Mutability, | |
a7813a04 XL |
438 | TupleSize(x) => TupleSize(x), |
439 | FixedArraySize(x) => FixedArraySize(x), | |
a7813a04 | 440 | ArgCount => ArgCount, |
9e0c209e SL |
441 | RegionsDoesNotOutlive(a, b) => { |
442 | return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) | |
443 | } | |
ea8adc8c XL |
444 | RegionsInsufficientlyPolymorphic(a, b) => { |
445 | return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b)) | |
9e0c209e | 446 | } |
ea8adc8c XL |
447 | RegionsOverlyPolymorphic(a, b) => { |
448 | return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b)) | |
a7813a04 | 449 | } |
a7813a04 XL |
450 | IntMismatch(x) => IntMismatch(x), |
451 | FloatMismatch(x) => FloatMismatch(x), | |
452 | Traits(x) => Traits(x), | |
a7813a04 | 453 | VariadicMismatch(x) => VariadicMismatch(x), |
ff7c6d11 | 454 | CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)), |
041b39d2 | 455 | ProjectionMismatched(x) => ProjectionMismatched(x), |
a7813a04 | 456 | ProjectionBoundsLength(x) => ProjectionBoundsLength(x), |
a7813a04 | 457 | Sorts(ref x) => return tcx.lift(x).map(Sorts), |
abe05a73 | 458 | OldStyleLUB(ref x) => return tcx.lift(x).map(OldStyleLUB), |
0531ce1d | 459 | ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch) |
a7813a04 XL |
460 | }) |
461 | } | |
462 | } | |
463 | ||
ea8adc8c XL |
464 | impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> { |
465 | type Lifted = ConstEvalErr<'tcx>; | |
466 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
8faf50e0 | 467 | tcx.lift(&self.error).map(|error| { |
ea8adc8c XL |
468 | ConstEvalErr { |
469 | span: self.span, | |
8faf50e0 XL |
470 | stacktrace: self.stacktrace.clone(), |
471 | error, | |
ea8adc8c XL |
472 | } |
473 | }) | |
474 | } | |
475 | } | |
476 | ||
0531ce1d XL |
477 | impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> { |
478 | type Lifted = interpret::EvalError<'tcx>; | |
83c7162d XL |
479 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
480 | Some(interpret::EvalError { | |
481 | kind: tcx.lift(&self.kind)?, | |
83c7162d XL |
482 | }) |
483 | } | |
484 | } | |
485 | ||
486 | impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> { | |
487 | type Lifted = interpret::EvalErrorKind<'tcx, <O as Lift<'tcx>>::Lifted>; | |
0531ce1d XL |
488 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { |
489 | use ::mir::interpret::EvalErrorKind::*; | |
83c7162d | 490 | Some(match *self { |
0531ce1d | 491 | MachineError(ref err) => MachineError(err.clone()), |
b7449926 XL |
492 | FunctionAbiMismatch(a, b) => FunctionAbiMismatch(a, b), |
493 | FunctionArgMismatch(a, b) => FunctionArgMismatch( | |
0531ce1d XL |
494 | tcx.lift(&a)?, |
495 | tcx.lift(&b)?, | |
496 | ), | |
0bf4aa26 XL |
497 | FunctionRetMismatch(a, b) => FunctionRetMismatch( |
498 | tcx.lift(&a)?, | |
499 | tcx.lift(&b)?, | |
500 | ), | |
b7449926 | 501 | FunctionArgCountMismatch => FunctionArgCountMismatch, |
0531ce1d XL |
502 | NoMirFor(ref s) => NoMirFor(s.clone()), |
503 | UnterminatedCString(ptr) => UnterminatedCString(ptr), | |
504 | DanglingPointerDeref => DanglingPointerDeref, | |
505 | DoubleFree => DoubleFree, | |
506 | InvalidMemoryAccess => InvalidMemoryAccess, | |
507 | InvalidFunctionPointer => InvalidFunctionPointer, | |
508 | InvalidBool => InvalidBool, | |
b7449926 | 509 | InvalidDiscriminant(val) => InvalidDiscriminant(val), |
0531ce1d XL |
510 | PointerOutOfBounds { |
511 | ptr, | |
512 | access, | |
513 | allocation_size, | |
514 | } => PointerOutOfBounds { ptr, access, allocation_size }, | |
515 | InvalidNullPointerUsage => InvalidNullPointerUsage, | |
516 | ReadPointerAsBytes => ReadPointerAsBytes, | |
517 | ReadBytesAsPointer => ReadBytesAsPointer, | |
8faf50e0 | 518 | ReadForeignStatic => ReadForeignStatic, |
0531ce1d | 519 | InvalidPointerMath => InvalidPointerMath, |
b7449926 | 520 | ReadUndefBytes(offset) => ReadUndefBytes(offset), |
0531ce1d XL |
521 | DeadLocal => DeadLocal, |
522 | InvalidBoolOp(bop) => InvalidBoolOp(bop), | |
523 | Unimplemented(ref s) => Unimplemented(s.clone()), | |
524 | DerefFunctionPointer => DerefFunctionPointer, | |
525 | ExecuteMemory => ExecuteMemory, | |
83c7162d XL |
526 | BoundsCheck { ref len, ref index } => BoundsCheck { |
527 | len: tcx.lift(len)?, | |
528 | index: tcx.lift(index)?, | |
529 | }, | |
0531ce1d | 530 | Intrinsic(ref s) => Intrinsic(s.clone()), |
0531ce1d XL |
531 | InvalidChar(c) => InvalidChar(c), |
532 | StackFrameLimitReached => StackFrameLimitReached, | |
533 | OutOfTls => OutOfTls, | |
534 | TlsOutOfBounds => TlsOutOfBounds, | |
535 | AbiViolation(ref s) => AbiViolation(s.clone()), | |
536 | AlignmentCheckFailed { | |
537 | required, | |
538 | has, | |
539 | } => AlignmentCheckFailed { required, has }, | |
540 | MemoryLockViolation { | |
541 | ptr, | |
542 | len, | |
543 | frame, | |
544 | access, | |
545 | ref lock, | |
546 | } => MemoryLockViolation { ptr, len, frame, access, lock: lock.clone() }, | |
547 | MemoryAcquireConflict { | |
548 | ptr, | |
549 | len, | |
550 | kind, | |
551 | ref lock, | |
552 | } => MemoryAcquireConflict { ptr, len, kind, lock: lock.clone() }, | |
553 | InvalidMemoryLockRelease { | |
554 | ptr, | |
555 | len, | |
556 | frame, | |
557 | ref lock, | |
558 | } => InvalidMemoryLockRelease { ptr, len, frame, lock: lock.clone() }, | |
559 | DeallocatedLockedMemory { | |
560 | ptr, | |
561 | ref lock, | |
562 | } => DeallocatedLockedMemory { ptr, lock: lock.clone() }, | |
563 | ValidationFailure(ref s) => ValidationFailure(s.clone()), | |
564 | CalledClosureAsFunction => CalledClosureAsFunction, | |
565 | VtableForArgumentlessMethod => VtableForArgumentlessMethod, | |
566 | ModifiedConstantMemory => ModifiedConstantMemory, | |
567 | AssumptionNotHeld => AssumptionNotHeld, | |
568 | InlineAsm => InlineAsm, | |
569 | TypeNotPrimitive(ty) => TypeNotPrimitive(tcx.lift(&ty)?), | |
570 | ReallocatedWrongMemoryKind(ref a, ref b) => { | |
571 | ReallocatedWrongMemoryKind(a.clone(), b.clone()) | |
572 | }, | |
573 | DeallocatedWrongMemoryKind(ref a, ref b) => { | |
574 | DeallocatedWrongMemoryKind(a.clone(), b.clone()) | |
575 | }, | |
576 | ReallocateNonBasePtr => ReallocateNonBasePtr, | |
577 | DeallocateNonBasePtr => DeallocateNonBasePtr, | |
578 | IncorrectAllocationInformation(a, b, c, d) => { | |
579 | IncorrectAllocationInformation(a, b, c, d) | |
580 | }, | |
581 | Layout(lay) => Layout(tcx.lift(&lay)?), | |
582 | HeapAllocZeroBytes => HeapAllocZeroBytes, | |
583 | HeapAllocNonPowerOfTwoAlignment(n) => HeapAllocNonPowerOfTwoAlignment(n), | |
584 | Unreachable => Unreachable, | |
b7449926 XL |
585 | Panic { ref msg, ref file, line, col } => Panic { |
586 | msg: msg.clone(), | |
587 | file: file.clone(), | |
588 | line, col, | |
589 | }, | |
0531ce1d XL |
590 | ReadFromReturnPointer => ReadFromReturnPointer, |
591 | PathNotFound(ref v) => PathNotFound(v.clone()), | |
592 | UnimplementedTraitSelection => UnimplementedTraitSelection, | |
593 | TypeckError => TypeckError, | |
8faf50e0 XL |
594 | TooGeneric => TooGeneric, |
595 | CheckMatchError => CheckMatchError, | |
596 | ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(&**err)?.into()), | |
83c7162d XL |
597 | OverflowNeg => OverflowNeg, |
598 | Overflow(op) => Overflow(op), | |
599 | DivisionByZero => DivisionByZero, | |
600 | RemainderByZero => RemainderByZero, | |
601 | GeneratorResumedAfterReturn => GeneratorResumedAfterReturn, | |
602 | GeneratorResumedAfterPanic => GeneratorResumedAfterPanic, | |
8faf50e0 | 603 | InfiniteLoop => InfiniteLoop, |
ea8adc8c XL |
604 | }) |
605 | } | |
606 | } | |
607 | ||
608 | impl<'a, 'tcx> Lift<'tcx> for ty::layout::LayoutError<'a> { | |
609 | type Lifted = ty::layout::LayoutError<'tcx>; | |
610 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
611 | match *self { | |
612 | ty::layout::LayoutError::Unknown(ref ty) => { | |
613 | tcx.lift(ty).map(ty::layout::LayoutError::Unknown) | |
614 | } | |
615 | ty::layout::LayoutError::SizeOverflow(ref ty) => { | |
616 | tcx.lift(ty).map(ty::layout::LayoutError::SizeOverflow) | |
617 | } | |
618 | } | |
619 | } | |
620 | } | |
621 | ||
0531ce1d XL |
622 | impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { |
623 | type Lifted = ty::InstanceDef<'tcx>; | |
624 | fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> { | |
625 | match *self { | |
626 | ty::InstanceDef::Item(def_id) => | |
627 | Some(ty::InstanceDef::Item(def_id)), | |
628 | ty::InstanceDef::Intrinsic(def_id) => | |
629 | Some(ty::InstanceDef::Intrinsic(def_id)), | |
630 | ty::InstanceDef::FnPtrShim(def_id, ref ty) => | |
631 | Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)), | |
632 | ty::InstanceDef::Virtual(def_id, n) => | |
633 | Some(ty::InstanceDef::Virtual(def_id, n)), | |
634 | ty::InstanceDef::ClosureOnceShim { call_once } => | |
635 | Some(ty::InstanceDef::ClosureOnceShim { call_once }), | |
636 | ty::InstanceDef::DropGlue(def_id, ref ty) => | |
637 | Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)), | |
638 | ty::InstanceDef::CloneShim(def_id, ref ty) => | |
639 | Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)), | |
640 | } | |
641 | } | |
642 | } | |
643 | ||
644 | BraceStructLiftImpl! { | |
645 | impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> { | |
646 | type Lifted = ty::Instance<'tcx>; | |
647 | def, substs | |
648 | } | |
649 | } | |
650 | ||
651 | BraceStructLiftImpl! { | |
652 | impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> { | |
653 | type Lifted = interpret::GlobalId<'tcx>; | |
654 | instance, promoted | |
655 | } | |
656 | } | |
657 | ||
e9174d1e SL |
658 | /////////////////////////////////////////////////////////////////////////// |
659 | // TypeFoldable implementations. | |
660 | // | |
661 | // Ideally, each type should invoke `folder.fold_foo(self)` and | |
662 | // nothing else. In some cases, though, we haven't gotten around to | |
663 | // adding methods on the `folder` yet, and thus the folding is | |
664 | // hard-coded here. This is less-flexible, because folders cannot | |
665 | // override the behavior, but there are a lot of random types and one | |
666 | // can easily refactor the folding into the TypeFolder trait as | |
667 | // needed. | |
668 | ||
0531ce1d XL |
669 | /// AdtDefs are basically the same as a DefId. |
670 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { | |
671 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { | |
672 | *self | |
673 | } | |
674 | ||
675 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool { | |
676 | false | |
677 | } | |
678 | } | |
679 | ||
e9174d1e | 680 | impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { |
a7813a04 | 681 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) { |
e9174d1e SL |
682 | (self.0.fold_with(folder), self.1.fold_with(folder)) |
683 | } | |
9cc50fc6 SL |
684 | |
685 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
686 | self.0.visit_with(visitor) || self.1.visit_with(visitor) | |
687 | } | |
e9174d1e SL |
688 | } |
689 | ||
0531ce1d XL |
690 | EnumTypeFoldableImpl! { |
691 | impl<'tcx, T> TypeFoldable<'tcx> for Option<T> { | |
692 | (Some)(a), | |
693 | (None), | |
694 | } where T: TypeFoldable<'tcx> | |
e9174d1e SL |
695 | } |
696 | ||
697 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> { | |
a7813a04 | 698 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
e9174d1e SL |
699 | Rc::new((**self).fold_with(folder)) |
700 | } | |
9cc50fc6 SL |
701 | |
702 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
703 | (**self).visit_with(visitor) | |
704 | } | |
e9174d1e SL |
705 | } |
706 | ||
707 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> { | |
a7813a04 | 708 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
e9174d1e SL |
709 | let content: T = (**self).fold_with(folder); |
710 | box content | |
711 | } | |
9cc50fc6 SL |
712 | |
713 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
714 | (**self).visit_with(visitor) | |
715 | } | |
e9174d1e SL |
716 | } |
717 | ||
718 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> { | |
a7813a04 | 719 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
e9174d1e SL |
720 | self.iter().map(|t| t.fold_with(folder)).collect() |
721 | } | |
9cc50fc6 SL |
722 | |
723 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
724 | self.iter().any(|t| t.visit_with(visitor)) | |
725 | } | |
e9174d1e SL |
726 | } |
727 | ||
0bf4aa26 XL |
728 | impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { |
729 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { | |
730 | self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice() | |
731 | } | |
732 | ||
733 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
734 | self.iter().any(|t| t.visit_with(visitor)) | |
735 | } | |
736 | } | |
737 | ||
e9174d1e | 738 | impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> { |
a7813a04 | 739 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
83c7162d | 740 | self.map_bound_ref(|ty| ty.fold_with(folder)) |
9cc50fc6 SL |
741 | } |
742 | ||
a7813a04 | 743 | fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
e9174d1e SL |
744 | folder.fold_binder(self) |
745 | } | |
9cc50fc6 SL |
746 | |
747 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
83c7162d | 748 | self.skip_binder().visit_with(visitor) |
54a0048b SL |
749 | } |
750 | ||
751 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
752 | visitor.visit_binder(self) | |
9cc50fc6 | 753 | } |
e9174d1e SL |
754 | } |
755 | ||
ff7c6d11 XL |
756 | BraceStructTypeFoldableImpl! { |
757 | impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds } | |
7cac9316 XL |
758 | } |
759 | ||
b7449926 | 760 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> { |
a7813a04 | 761 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
b7449926 | 762 | let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>(); |
476ff2be SL |
763 | folder.tcx().intern_existential_predicates(&v) |
764 | } | |
765 | ||
766 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
767 | self.iter().any(|p| p.visit_with(visitor)) | |
768 | } | |
769 | } | |
770 | ||
0531ce1d XL |
771 | EnumTypeFoldableImpl! { |
772 | impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> { | |
773 | (ty::ExistentialPredicate::Trait)(a), | |
774 | (ty::ExistentialPredicate::Projection)(a), | |
775 | (ty::ExistentialPredicate::AutoTrait)(a), | |
776 | } | |
777 | } | |
778 | ||
b7449926 | 779 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { |
0531ce1d | 780 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
b7449926 | 781 | let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>(); |
0531ce1d XL |
782 | folder.tcx().intern_type_list(&v) |
783 | } | |
784 | ||
785 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
786 | self.iter().any(|t| t.visit_with(visitor)) | |
787 | } | |
788 | } | |
789 | ||
0bf4aa26 XL |
790 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind<'tcx>> { |
791 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { | |
792 | let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>(); | |
793 | folder.tcx().intern_projs(&v) | |
794 | } | |
795 | ||
796 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
797 | self.iter().any(|t| t.visit_with(visitor)) | |
798 | } | |
799 | } | |
800 | ||
0531ce1d XL |
801 | impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { |
802 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { | |
803 | use ty::InstanceDef::*; | |
804 | Self { | |
805 | substs: self.substs.fold_with(folder), | |
806 | def: match self.def { | |
807 | Item(did) => Item(did.fold_with(folder)), | |
808 | Intrinsic(did) => Intrinsic(did.fold_with(folder)), | |
809 | FnPtrShim(did, ty) => FnPtrShim( | |
810 | did.fold_with(folder), | |
811 | ty.fold_with(folder), | |
812 | ), | |
813 | Virtual(did, i) => Virtual( | |
814 | did.fold_with(folder), | |
815 | i, | |
816 | ), | |
817 | ClosureOnceShim { call_once } => ClosureOnceShim { | |
818 | call_once: call_once.fold_with(folder), | |
819 | }, | |
820 | DropGlue(did, ty) => DropGlue( | |
821 | did.fold_with(folder), | |
822 | ty.fold_with(folder), | |
823 | ), | |
824 | CloneShim(did, ty) => CloneShim( | |
825 | did.fold_with(folder), | |
826 | ty.fold_with(folder), | |
827 | ), | |
828 | }, | |
9cc50fc6 SL |
829 | } |
830 | } | |
831 | ||
832 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
0531ce1d XL |
833 | use ty::InstanceDef::*; |
834 | self.substs.visit_with(visitor) || | |
835 | match self.def { | |
0bf4aa26 XL |
836 | Item(did) | Intrinsic(did) | Virtual(did, _) => { |
837 | did.visit_with(visitor) | |
0531ce1d | 838 | }, |
0bf4aa26 XL |
839 | FnPtrShim(did, ty) | CloneShim(did, ty) => { |
840 | did.visit_with(visitor) || ty.visit_with(visitor) | |
0531ce1d | 841 | }, |
0bf4aa26 XL |
842 | DropGlue(did, ty) => { |
843 | did.visit_with(visitor) || ty.visit_with(visitor) | |
0531ce1d | 844 | }, |
0bf4aa26 | 845 | ClosureOnceShim { call_once } => call_once.visit_with(visitor), |
476ff2be | 846 | } |
9cc50fc6 | 847 | } |
e9174d1e SL |
848 | } |
849 | ||
0531ce1d | 850 | impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { |
a7813a04 | 851 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
0531ce1d XL |
852 | Self { |
853 | instance: self.instance.fold_with(folder), | |
854 | promoted: self.promoted | |
855 | } | |
a7813a04 XL |
856 | } |
857 | ||
858 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
0531ce1d | 859 | self.instance.visit_with(visitor) |
a7813a04 XL |
860 | } |
861 | } | |
862 | ||
e9174d1e | 863 | impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { |
a7813a04 | 864 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
9cc50fc6 | 865 | let sty = match self.sty { |
b7449926 XL |
866 | ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)), |
867 | ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)), | |
868 | ty::Slice(typ) => ty::Slice(typ.fold_with(folder)), | |
869 | ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)), | |
870 | ty::Dynamic(ref trait_ty, ref region) => | |
871 | ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)), | |
872 | ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)), | |
873 | ty::FnDef(def_id, substs) => { | |
874 | ty::FnDef(def_id, substs.fold_with(folder)) | |
9cc50fc6 | 875 | } |
b7449926 XL |
876 | ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)), |
877 | ty::Ref(ref r, ty, mutbl) => { | |
878 | ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl) | |
9cc50fc6 | 879 | } |
b7449926 XL |
880 | ty::Generator(did, substs, movability) => { |
881 | ty::Generator( | |
94b46f34 XL |
882 | did, |
883 | substs.fold_with(folder), | |
884 | movability) | |
ea8adc8c | 885 | } |
b7449926 XL |
886 | ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)), |
887 | ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)), | |
888 | ty::Projection(ref data) => ty::Projection(data.fold_with(folder)), | |
0bf4aa26 XL |
889 | ty::UnnormalizedProjection(ref data) => { |
890 | ty::UnnormalizedProjection(data.fold_with(folder)) | |
891 | } | |
b7449926 XL |
892 | ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)), |
893 | ty::Bool | ty::Char | ty::Str | ty::Int(_) | | |
894 | ty::Uint(_) | ty::Float(_) | ty::Error | ty::Infer(_) | | |
895 | ty::Param(..) | ty::Never | ty::Foreign(..) => return self | |
9cc50fc6 | 896 | }; |
476ff2be SL |
897 | |
898 | if self.sty == sty { | |
899 | self | |
900 | } else { | |
901 | folder.tcx().mk_ty(sty) | |
902 | } | |
9cc50fc6 SL |
903 | } |
904 | ||
a7813a04 | 905 | fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
e9174d1e SL |
906 | folder.fold_ty(*self) |
907 | } | |
9cc50fc6 SL |
908 | |
909 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
910 | match self.sty { | |
b7449926 XL |
911 | ty::RawPtr(ref tm) => tm.visit_with(visitor), |
912 | ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor), | |
913 | ty::Slice(typ) => typ.visit_with(visitor), | |
914 | ty::Adt(_, substs) => substs.visit_with(visitor), | |
915 | ty::Dynamic(ref trait_ty, ref reg) => | |
476ff2be | 916 | trait_ty.visit_with(visitor) || reg.visit_with(visitor), |
b7449926 XL |
917 | ty::Tuple(ts) => ts.visit_with(visitor), |
918 | ty::FnDef(_, substs) => substs.visit_with(visitor), | |
919 | ty::FnPtr(ref f) => f.visit_with(visitor), | |
920 | ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor), | |
921 | ty::Generator(_did, ref substs, _) => { | |
94b46f34 | 922 | substs.visit_with(visitor) |
ea8adc8c | 923 | } |
b7449926 XL |
924 | ty::GeneratorWitness(ref types) => types.visit_with(visitor), |
925 | ty::Closure(_did, ref substs) => substs.visit_with(visitor), | |
0bf4aa26 XL |
926 | ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => { |
927 | data.visit_with(visitor) | |
928 | } | |
b7449926 XL |
929 | ty::Opaque(_, ref substs) => substs.visit_with(visitor), |
930 | ty::Bool | ty::Char | ty::Str | ty::Int(_) | | |
931 | ty::Uint(_) | ty::Float(_) | ty::Error | ty::Infer(_) | | |
932 | ty::Param(..) | ty::Never | ty::Foreign(..) => false, | |
9cc50fc6 SL |
933 | } |
934 | } | |
935 | ||
936 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
937 | visitor.visit_ty(self) | |
938 | } | |
e9174d1e SL |
939 | } |
940 | ||
0531ce1d XL |
941 | BraceStructTypeFoldableImpl! { |
942 | impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> { | |
943 | ty, mutbl | |
9cc50fc6 | 944 | } |
e9174d1e SL |
945 | } |
946 | ||
ff7c6d11 XL |
947 | BraceStructTypeFoldableImpl! { |
948 | impl<'tcx> TypeFoldable<'tcx> for ty::GenSig<'tcx> { | |
949 | yield_ty, return_ty | |
ea8adc8c XL |
950 | } |
951 | } | |
952 | ||
0531ce1d XL |
953 | BraceStructTypeFoldableImpl! { |
954 | impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { | |
955 | inputs_and_output, variadic, unsafety, abi | |
9cc50fc6 | 956 | } |
e9174d1e SL |
957 | } |
958 | ||
ff7c6d11 XL |
959 | BraceStructTypeFoldableImpl! { |
960 | impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { def_id, substs } | |
9e0c209e SL |
961 | } |
962 | ||
ff7c6d11 XL |
963 | BraceStructTypeFoldableImpl! { |
964 | impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> { def_id, substs } | |
e9174d1e SL |
965 | } |
966 | ||
ff7c6d11 XL |
967 | BraceStructTypeFoldableImpl! { |
968 | impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> { | |
969 | impl_def_id, | |
970 | self_ty, | |
971 | trait_ref, | |
972 | predicates, | |
54a0048b SL |
973 | } |
974 | } | |
975 | ||
7cac9316 | 976 | impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { |
a7813a04 | 977 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { |
9cc50fc6 SL |
978 | *self |
979 | } | |
980 | ||
a7813a04 | 981 | fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
e9174d1e SL |
982 | folder.fold_region(*self) |
983 | } | |
9cc50fc6 SL |
984 | |
985 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool { | |
986 | false | |
987 | } | |
988 | ||
989 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
990 | visitor.visit_region(*self) | |
991 | } | |
e9174d1e SL |
992 | } |
993 | ||
0531ce1d XL |
994 | BraceStructTypeFoldableImpl! { |
995 | impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { | |
996 | substs, | |
9cc50fc6 | 997 | } |
e9174d1e SL |
998 | } |
999 | ||
0531ce1d | 1000 | BraceStructTypeFoldableImpl! { |
94b46f34 XL |
1001 | impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> { |
1002 | substs, | |
ea8adc8c XL |
1003 | } |
1004 | } | |
1005 | ||
ff7c6d11 XL |
1006 | BraceStructTypeFoldableImpl! { |
1007 | impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjustment<'tcx> { | |
1008 | kind, | |
1009 | target, | |
7cac9316 XL |
1010 | } |
1011 | } | |
1012 | ||
0531ce1d XL |
1013 | EnumTypeFoldableImpl! { |
1014 | impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> { | |
1015 | (ty::adjustment::Adjust::NeverToAny), | |
1016 | (ty::adjustment::Adjust::ReifyFnPointer), | |
1017 | (ty::adjustment::Adjust::UnsafeFnPointer), | |
1018 | (ty::adjustment::Adjust::ClosureFnPointer), | |
1019 | (ty::adjustment::Adjust::MutToConstPointer), | |
1020 | (ty::adjustment::Adjust::Unsize), | |
1021 | (ty::adjustment::Adjust::Deref)(a), | |
1022 | (ty::adjustment::Adjust::Borrow)(a), | |
7cac9316 XL |
1023 | } |
1024 | } | |
1025 | ||
0531ce1d XL |
1026 | BraceStructTypeFoldableImpl! { |
1027 | impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> { | |
1028 | region, mutbl, | |
9cc50fc6 | 1029 | } |
e9174d1e SL |
1030 | } |
1031 | ||
0531ce1d XL |
1032 | EnumTypeFoldableImpl! { |
1033 | impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> { | |
1034 | (ty::adjustment::AutoBorrow::Ref)(a, b), | |
1035 | (ty::adjustment::AutoBorrow::RawPtr)(m), | |
9cc50fc6 | 1036 | } |
e9174d1e SL |
1037 | } |
1038 | ||
ff7c6d11 XL |
1039 | BraceStructTypeFoldableImpl! { |
1040 | impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { | |
1041 | parent, predicates | |
476ff2be SL |
1042 | } |
1043 | } | |
1044 | ||
b7449926 | 1045 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { |
7cac9316 | 1046 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
b7449926 | 1047 | let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>(); |
7cac9316 XL |
1048 | folder.tcx().intern_predicates(&v) |
1049 | } | |
1050 | ||
1051 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
1052 | self.iter().any(|p| p.visit_with(visitor)) | |
1053 | } | |
1054 | } | |
1055 | ||
0531ce1d XL |
1056 | EnumTypeFoldableImpl! { |
1057 | impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { | |
1058 | (ty::Predicate::Trait)(a), | |
1059 | (ty::Predicate::Subtype)(a), | |
1060 | (ty::Predicate::RegionOutlives)(a), | |
1061 | (ty::Predicate::TypeOutlives)(a), | |
1062 | (ty::Predicate::Projection)(a), | |
1063 | (ty::Predicate::WellFormed)(a), | |
1064 | (ty::Predicate::ClosureKind)(a, b, c), | |
1065 | (ty::Predicate::ObjectSafe)(a), | |
1066 | (ty::Predicate::ConstEvaluatable)(a, b), | |
9cc50fc6 | 1067 | } |
e9174d1e SL |
1068 | } |
1069 | ||
ff7c6d11 XL |
1070 | BraceStructTypeFoldableImpl! { |
1071 | impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> { | |
1072 | projection_ty, ty | |
9cc50fc6 | 1073 | } |
e9174d1e SL |
1074 | } |
1075 | ||
ff7c6d11 XL |
1076 | BraceStructTypeFoldableImpl! { |
1077 | impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> { | |
1078 | ty, substs, item_def_id | |
9e0c209e SL |
1079 | } |
1080 | } | |
1081 | ||
ff7c6d11 XL |
1082 | BraceStructTypeFoldableImpl! { |
1083 | impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> { | |
1084 | substs, item_def_id | |
9cc50fc6 | 1085 | } |
e9174d1e SL |
1086 | } |
1087 | ||
ff7c6d11 XL |
1088 | BraceStructTypeFoldableImpl! { |
1089 | impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> { | |
1090 | predicates | |
9cc50fc6 | 1091 | } |
e9174d1e SL |
1092 | } |
1093 | ||
0531ce1d XL |
1094 | BraceStructTypeFoldableImpl! { |
1095 | impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> { | |
1096 | param_env, value | |
1097 | } where T: TypeFoldable<'tcx> | |
cc61c64b XL |
1098 | } |
1099 | ||
0531ce1d XL |
1100 | BraceStructTypeFoldableImpl! { |
1101 | impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> { | |
1102 | a_is_expected, a, b | |
9cc50fc6 | 1103 | } |
e9174d1e SL |
1104 | } |
1105 | ||
0531ce1d XL |
1106 | BraceStructTypeFoldableImpl! { |
1107 | impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { | |
1108 | trait_ref | |
9cc50fc6 | 1109 | } |
e9174d1e SL |
1110 | } |
1111 | ||
0531ce1d XL |
1112 | TupleStructTypeFoldableImpl! { |
1113 | impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> { | |
1114 | a, b | |
1115 | } where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>, | |
e9174d1e SL |
1116 | } |
1117 | ||
0531ce1d XL |
1118 | BraceStructTypeFoldableImpl! { |
1119 | impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { | |
1120 | def, span, ty | |
5bcae85e SL |
1121 | } |
1122 | } | |
8bb4bdeb | 1123 | |
0531ce1d XL |
1124 | BraceStructTypeFoldableImpl! { |
1125 | impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> { | |
1126 | expected, found | |
1127 | } where T: TypeFoldable<'tcx> | |
041b39d2 XL |
1128 | } |
1129 | ||
8bb4bdeb XL |
1130 | impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> { |
1131 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { | |
1132 | self.iter().map(|x| x.fold_with(folder)).collect() | |
1133 | } | |
1134 | ||
1135 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
1136 | self.iter().any(|t| t.visit_with(visitor)) | |
1137 | } | |
1138 | } | |
041b39d2 | 1139 | |
0531ce1d XL |
1140 | EnumTypeFoldableImpl! { |
1141 | impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { | |
1142 | (ty::error::TypeError::Mismatch), | |
1143 | (ty::error::TypeError::UnsafetyMismatch)(x), | |
1144 | (ty::error::TypeError::AbiMismatch)(x), | |
1145 | (ty::error::TypeError::Mutability), | |
1146 | (ty::error::TypeError::TupleSize)(x), | |
1147 | (ty::error::TypeError::FixedArraySize)(x), | |
1148 | (ty::error::TypeError::ArgCount), | |
1149 | (ty::error::TypeError::RegionsDoesNotOutlive)(a, b), | |
1150 | (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b), | |
1151 | (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b), | |
1152 | (ty::error::TypeError::IntMismatch)(x), | |
1153 | (ty::error::TypeError::FloatMismatch)(x), | |
1154 | (ty::error::TypeError::Traits)(x), | |
1155 | (ty::error::TypeError::VariadicMismatch)(x), | |
1156 | (ty::error::TypeError::CyclicTy)(t), | |
1157 | (ty::error::TypeError::ProjectionMismatched)(x), | |
1158 | (ty::error::TypeError::ProjectionBoundsLength)(x), | |
1159 | (ty::error::TypeError::Sorts)(x), | |
1160 | (ty::error::TypeError::ExistentialMismatch)(x), | |
1161 | (ty::error::TypeError::OldStyleLUB)(x), | |
041b39d2 XL |
1162 | } |
1163 | } | |
ea8adc8c | 1164 | |
8faf50e0 | 1165 | impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { |
ea8adc8c XL |
1166 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { |
1167 | match *self { | |
8faf50e0 XL |
1168 | ConstValue::Scalar(v) => ConstValue::Scalar(v), |
1169 | ConstValue::ScalarPair(a, b) => ConstValue::ScalarPair(a, b), | |
b7449926 | 1170 | ConstValue::ByRef(id, alloc, offset) => ConstValue::ByRef(id, alloc, offset), |
8faf50e0 XL |
1171 | ConstValue::Unevaluated(def_id, substs) => { |
1172 | ConstValue::Unevaluated(def_id, substs.fold_with(folder)) | |
ea8adc8c XL |
1173 | } |
1174 | } | |
1175 | } | |
1176 | ||
1177 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
1178 | match *self { | |
8faf50e0 XL |
1179 | ConstValue::Scalar(_) | |
1180 | ConstValue::ScalarPair(_, _) | | |
b7449926 | 1181 | ConstValue::ByRef(_, _, _) => false, |
8faf50e0 | 1182 | ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor), |
ea8adc8c XL |
1183 | } |
1184 | } | |
1185 | } | |
1186 | ||
1187 | impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { | |
1188 | fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { | |
1189 | let ty = self.ty.fold_with(folder); | |
1190 | let val = self.val.fold_with(folder); | |
1191 | folder.tcx().mk_const(ty::Const { | |
1192 | ty, | |
1193 | val | |
1194 | }) | |
1195 | } | |
1196 | ||
1197 | fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { | |
1198 | folder.fold_const(*self) | |
1199 | } | |
1200 | ||
1201 | fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
1202 | self.ty.visit_with(visitor) || self.val.visit_with(visitor) | |
1203 | } | |
1204 | ||
1205 | fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { | |
1206 | visitor.visit_const(self) | |
1207 | } | |
1208 | } |