]> git.proxmox.com Git - rustc.git/blob - src/librustc/ty/structural_impls.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / librustc / ty / structural_impls.rs
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
11 use infer::type_variable;
12 use ty::{self, Lift, Ty, TyCtxt};
13 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
14 use rustc_data_structures::accumulate_vec::AccumulateVec;
15 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
16
17 use std::rc::Rc;
18 use syntax::abi;
19
20 use hir;
21
22 ///////////////////////////////////////////////////////////////////////////
23 // Lift implementations
24
25 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
26 type Lifted = (A::Lifted, B::Lifted);
27 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
28 tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
29 }
30 }
31
32 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
33 type Lifted = Option<T::Lifted>;
34 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
35 match *self {
36 Some(ref x) => tcx.lift(x).map(Some),
37 None => Some(None)
38 }
39 }
40 }
41
42 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
43 type Lifted = Result<T::Lifted, E::Lifted>;
44 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
45 match *self {
46 Ok(ref x) => tcx.lift(x).map(Ok),
47 Err(ref e) => tcx.lift(e).map(Err)
48 }
49 }
50 }
51
52 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
53 type Lifted = Vec<T::Lifted>;
54 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
55 // type annotation needed to inform `projection_must_outlive`
56 let mut result : Vec<<T as Lift<'tcx>>::Lifted>
57 = Vec::with_capacity(self.len());
58 for x in self {
59 if let Some(value) = tcx.lift(x) {
60 result.push(value);
61 } else {
62 return None;
63 }
64 }
65 Some(result)
66 }
67 }
68
69 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
70 type Lifted = Vec<T::Lifted>;
71 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
72 tcx.lift(&self[..])
73 }
74 }
75
76 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
77 type Lifted = ty::TraitRef<'tcx>;
78 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
79 tcx.lift(&self.substs).map(|substs| ty::TraitRef {
80 def_id: self.def_id,
81 substs: substs
82 })
83 }
84 }
85
86 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
87 type Lifted = ty::ExistentialTraitRef<'tcx>;
88 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
89 tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
90 def_id: self.def_id,
91 substs: substs
92 })
93 }
94 }
95
96 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
97 type Lifted = ty::TraitPredicate<'tcx>;
98 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
99 -> Option<ty::TraitPredicate<'tcx>> {
100 tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
101 trait_ref: trait_ref
102 })
103 }
104 }
105
106 impl<'a, 'tcx> Lift<'tcx> for ty::EquatePredicate<'a> {
107 type Lifted = ty::EquatePredicate<'tcx>;
108 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
109 -> Option<ty::EquatePredicate<'tcx>> {
110 tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::EquatePredicate(a, b))
111 }
112 }
113
114 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
115 type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
116 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
117 tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
118 }
119 }
120
121 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
122 type Lifted = ty::ProjectionTy<'tcx>;
123 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
124 -> Option<ty::ProjectionTy<'tcx>> {
125 tcx.lift(&self.trait_ref).map(|trait_ref| {
126 ty::ProjectionTy {
127 trait_ref: trait_ref,
128 item_name: self.item_name
129 }
130 })
131 }
132 }
133
134 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
135 type Lifted = ty::ProjectionPredicate<'tcx>;
136 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
137 -> Option<ty::ProjectionPredicate<'tcx>> {
138 tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
139 ty::ProjectionPredicate {
140 projection_ty: projection_ty,
141 ty: ty
142 }
143 })
144 }
145 }
146
147 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
148 type Lifted = ty::ExistentialProjection<'tcx>;
149 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
150 tcx.lift(&(self.trait_ref, self.ty)).map(|(trait_ref, ty)| {
151 ty::ExistentialProjection {
152 trait_ref: trait_ref,
153 item_name: self.item_name,
154 ty: ty
155 }
156 })
157 }
158 }
159
160 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
161 type Lifted = ty::Predicate<'tcx>;
162 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
163 match *self {
164 ty::Predicate::Trait(ref binder) => {
165 tcx.lift(binder).map(ty::Predicate::Trait)
166 }
167 ty::Predicate::Equate(ref binder) => {
168 tcx.lift(binder).map(ty::Predicate::Equate)
169 }
170 ty::Predicate::RegionOutlives(ref binder) => {
171 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
172 }
173 ty::Predicate::TypeOutlives(ref binder) => {
174 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
175 }
176 ty::Predicate::Projection(ref binder) => {
177 tcx.lift(binder).map(ty::Predicate::Projection)
178 }
179 ty::Predicate::WellFormed(ty) => {
180 tcx.lift(&ty).map(ty::Predicate::WellFormed)
181 }
182 ty::Predicate::ClosureKind(closure_def_id, kind) => {
183 Some(ty::Predicate::ClosureKind(closure_def_id, kind))
184 }
185 ty::Predicate::ObjectSafe(trait_def_id) => {
186 Some(ty::Predicate::ObjectSafe(trait_def_id))
187 }
188 }
189 }
190 }
191
192 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
193 type Lifted = ty::Binder<T::Lifted>;
194 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
195 tcx.lift(&self.0).map(|x| ty::Binder(x))
196 }
197 }
198
199 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
200 type Lifted = ty::ClosureSubsts<'tcx>;
201 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
202 tcx.lift(&self.substs).map(|substs| {
203 ty::ClosureSubsts { substs: substs }
204 })
205 }
206 }
207
208 impl<'a, 'tcx> Lift<'tcx> for ty::ItemSubsts<'a> {
209 type Lifted = ty::ItemSubsts<'tcx>;
210 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
211 tcx.lift(&self.substs).map(|substs| {
212 ty::ItemSubsts {
213 substs: substs
214 }
215 })
216 }
217 }
218
219 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
220 type Lifted = ty::adjustment::AutoBorrow<'tcx>;
221 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
222 match *self {
223 ty::adjustment::AutoBorrow::Ref(r, m) => {
224 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
225 }
226 ty::adjustment::AutoBorrow::RawPtr(m) => {
227 Some(ty::adjustment::AutoBorrow::RawPtr(m))
228 }
229 }
230 }
231 }
232
233 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
234 type Lifted = ty::FnSig<'tcx>;
235 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
236 tcx.lift(&self.inputs_and_output).map(|x| {
237 ty::FnSig {
238 inputs_and_output: x,
239 variadic: self.variadic,
240 unsafety: self.unsafety,
241 abi: self.abi,
242 }
243 })
244 }
245 }
246
247 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
248 type Lifted = ty::error::ExpectedFound<T::Lifted>;
249 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
250 tcx.lift(&self.expected).and_then(|expected| {
251 tcx.lift(&self.found).map(|found| {
252 ty::error::ExpectedFound {
253 expected: expected,
254 found: found
255 }
256 })
257 })
258 }
259 }
260
261 impl<'a, 'tcx> Lift<'tcx> for type_variable::Default<'a> {
262 type Lifted = type_variable::Default<'tcx>;
263 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
264 tcx.lift(&self.ty).map(|ty| {
265 type_variable::Default {
266 ty: ty,
267 origin_span: self.origin_span,
268 def_id: self.def_id
269 }
270 })
271 }
272 }
273
274 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
275 type Lifted = ty::error::TypeError<'tcx>;
276 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
277 use ty::error::TypeError::*;
278
279 Some(match *self {
280 Mismatch => Mismatch,
281 UnsafetyMismatch(x) => UnsafetyMismatch(x),
282 AbiMismatch(x) => AbiMismatch(x),
283 Mutability => Mutability,
284 TupleSize(x) => TupleSize(x),
285 FixedArraySize(x) => FixedArraySize(x),
286 ArgCount => ArgCount,
287 RegionsDoesNotOutlive(a, b) => {
288 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
289 }
290 RegionsNotSame(a, b) => {
291 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNotSame(a, b))
292 }
293 RegionsNoOverlap(a, b) => {
294 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
295 }
296 RegionsInsufficientlyPolymorphic(a, b, ref c) => {
297 let c = c.clone();
298 return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b, c))
299 }
300 RegionsOverlyPolymorphic(a, b, ref c) => {
301 let c = c.clone();
302 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b, c))
303 }
304 IntMismatch(x) => IntMismatch(x),
305 FloatMismatch(x) => FloatMismatch(x),
306 Traits(x) => Traits(x),
307 VariadicMismatch(x) => VariadicMismatch(x),
308 CyclicTy => CyclicTy,
309 ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
310 ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
311
312 Sorts(ref x) => return tcx.lift(x).map(Sorts),
313 TyParamDefaultMismatch(ref x) => {
314 return tcx.lift(x).map(TyParamDefaultMismatch)
315 }
316 ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch)
317 })
318 }
319 }
320
321 ///////////////////////////////////////////////////////////////////////////
322 // TypeFoldable implementations.
323 //
324 // Ideally, each type should invoke `folder.fold_foo(self)` and
325 // nothing else. In some cases, though, we haven't gotten around to
326 // adding methods on the `folder` yet, and thus the folding is
327 // hard-coded here. This is less-flexible, because folders cannot
328 // override the behavior, but there are a lot of random types and one
329 // can easily refactor the folding into the TypeFolder trait as
330 // needed.
331
332 macro_rules! CopyImpls {
333 ($($ty:ty),+) => {
334 $(
335 impl<'tcx> TypeFoldable<'tcx> for $ty {
336 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> $ty {
337 *self
338 }
339
340 fn super_visit_with<F: TypeVisitor<'tcx>>(&self, _: &mut F) -> bool {
341 false
342 }
343 }
344 )+
345 }
346 }
347
348 CopyImpls! { (), hir::Unsafety, abi::Abi }
349
350 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
351 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
352 (self.0.fold_with(folder), self.1.fold_with(folder))
353 }
354
355 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
356 self.0.visit_with(visitor) || self.1.visit_with(visitor)
357 }
358 }
359
360 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option<T> {
361 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
362 self.as_ref().map(|t| t.fold_with(folder))
363 }
364
365 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
366 self.iter().any(|t| t.visit_with(visitor))
367 }
368 }
369
370 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
371 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
372 Rc::new((**self).fold_with(folder))
373 }
374
375 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
376 (**self).visit_with(visitor)
377 }
378 }
379
380 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
381 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
382 let content: T = (**self).fold_with(folder);
383 box content
384 }
385
386 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
387 (**self).visit_with(visitor)
388 }
389 }
390
391 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
392 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
393 self.iter().map(|t| t.fold_with(folder)).collect()
394 }
395
396 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
397 self.iter().any(|t| t.visit_with(visitor))
398 }
399 }
400
401 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
402 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
403 ty::Binder(self.0.fold_with(folder))
404 }
405
406 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
407 folder.fold_binder(self)
408 }
409
410 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
411 self.0.visit_with(visitor)
412 }
413
414 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
415 visitor.visit_binder(self)
416 }
417 }
418
419 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>> {
420 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
421 let v = self.iter().map(|p| p.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
422 folder.tcx().intern_existential_predicates(&v)
423 }
424
425 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
426 self.iter().any(|p| p.visit_with(visitor))
427 }
428 }
429
430 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
431 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
432 use ty::ExistentialPredicate::*;
433 match *self {
434 Trait(ref tr) => Trait(tr.fold_with(folder)),
435 Projection(ref p) => Projection(p.fold_with(folder)),
436 AutoTrait(did) => AutoTrait(did),
437 }
438 }
439
440 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
441 match *self {
442 ty::ExistentialPredicate::Trait(ref tr) => tr.visit_with(visitor),
443 ty::ExistentialPredicate::Projection(ref p) => p.visit_with(visitor),
444 ty::ExistentialPredicate::AutoTrait(_) => false,
445 }
446 }
447 }
448
449 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> {
450 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
451 let v = self.iter().map(|t| t.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
452 folder.tcx().intern_type_list(&v)
453 }
454
455 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
456 self.iter().any(|t| t.visit_with(visitor))
457 }
458 }
459
460 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
461 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
462 let sty = match self.sty {
463 ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)),
464 ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz),
465 ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)),
466 ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)),
467 ty::TyDynamic(ref trait_ty, ref region) =>
468 ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
469 ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
470 ty::TyFnDef(def_id, substs, f) => {
471 ty::TyFnDef(def_id,
472 substs.fold_with(folder),
473 f.fold_with(folder))
474 }
475 ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
476 ty::TyRef(ref r, tm) => {
477 ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
478 }
479 ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
480 ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)),
481 ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
482 ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
483 ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
484 ty::TyParam(..) | ty::TyNever => return self
485 };
486
487 if self.sty == sty {
488 self
489 } else {
490 folder.tcx().mk_ty(sty)
491 }
492 }
493
494 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
495 folder.fold_ty(*self)
496 }
497
498 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
499 match self.sty {
500 ty::TyRawPtr(ref tm) => tm.visit_with(visitor),
501 ty::TyArray(typ, _sz) => typ.visit_with(visitor),
502 ty::TySlice(typ) => typ.visit_with(visitor),
503 ty::TyAdt(_, substs) => substs.visit_with(visitor),
504 ty::TyDynamic(ref trait_ty, ref reg) =>
505 trait_ty.visit_with(visitor) || reg.visit_with(visitor),
506 ty::TyTuple(ts, _) => ts.visit_with(visitor),
507 ty::TyFnDef(_, substs, ref f) => {
508 substs.visit_with(visitor) || f.visit_with(visitor)
509 }
510 ty::TyFnPtr(ref f) => f.visit_with(visitor),
511 ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
512 ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
513 ty::TyProjection(ref data) => data.visit_with(visitor),
514 ty::TyAnon(_, ref substs) => substs.visit_with(visitor),
515 ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
516 ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
517 ty::TyParam(..) | ty::TyNever => false,
518 }
519 }
520
521 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
522 visitor.visit_ty(self)
523 }
524 }
525
526 impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
527 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
528 ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl }
529 }
530
531 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
532 folder.fold_mt(self)
533 }
534
535 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
536 self.ty.visit_with(visitor)
537 }
538 }
539
540 impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
541 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
542 let inputs_and_output = self.inputs_and_output.fold_with(folder);
543 ty::FnSig {
544 inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
545 variadic: self.variadic,
546 unsafety: self.unsafety,
547 abi: self.abi,
548 }
549 }
550
551 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
552 folder.fold_fn_sig(self)
553 }
554
555 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
556 self.inputs().iter().any(|i| i.visit_with(visitor)) ||
557 self.output().visit_with(visitor)
558 }
559 }
560
561 impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
562 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
563 ty::TraitRef {
564 def_id: self.def_id,
565 substs: self.substs.fold_with(folder),
566 }
567 }
568
569 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
570 self.substs.visit_with(visitor)
571 }
572
573 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
574 visitor.visit_trait_ref(*self)
575 }
576 }
577
578 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> {
579 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
580 ty::ExistentialTraitRef {
581 def_id: self.def_id,
582 substs: self.substs.fold_with(folder),
583 }
584 }
585
586 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
587 self.substs.visit_with(visitor)
588 }
589 }
590
591 impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
592 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
593 ty::ImplHeader {
594 impl_def_id: self.impl_def_id,
595 self_ty: self.self_ty.fold_with(folder),
596 trait_ref: self.trait_ref.map(|t| t.fold_with(folder)),
597 predicates: self.predicates.iter().map(|p| p.fold_with(folder)).collect(),
598 }
599 }
600
601 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
602 folder.fold_impl_header(self)
603 }
604
605 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
606 self.self_ty.visit_with(visitor) ||
607 self.trait_ref.map(|r| r.visit_with(visitor)).unwrap_or(false) ||
608 self.predicates.iter().any(|p| p.visit_with(visitor))
609 }
610 }
611
612 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
613 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
614 *self
615 }
616
617 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
618 folder.fold_region(*self)
619 }
620
621 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
622 false
623 }
624
625 fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
626 visitor.visit_region(*self)
627 }
628 }
629
630 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
631 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
632 ty::ClosureSubsts {
633 substs: self.substs.fold_with(folder),
634 }
635 }
636
637 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
638 self.substs.visit_with(visitor)
639 }
640 }
641
642 impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> {
643 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
644 ty::ItemSubsts {
645 substs: self.substs.fold_with(folder),
646 }
647 }
648
649 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
650 self.substs.visit_with(visitor)
651 }
652 }
653
654 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
655 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
656 match *self {
657 ty::adjustment::AutoBorrow::Ref(ref r, m) => {
658 ty::adjustment::AutoBorrow::Ref(r.fold_with(folder), m)
659 }
660 ty::adjustment::AutoBorrow::RawPtr(m) => ty::adjustment::AutoBorrow::RawPtr(m)
661 }
662 }
663
664 fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
665 folder.fold_autoref(self)
666 }
667
668 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
669 match *self {
670 ty::adjustment::AutoBorrow::Ref(r, _m) => r.visit_with(visitor),
671 ty::adjustment::AutoBorrow::RawPtr(_m) => false,
672 }
673 }
674 }
675
676 impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
677 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
678 ty::GenericPredicates {
679 parent: self.parent,
680 predicates: self.predicates.fold_with(folder),
681 }
682 }
683
684 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
685 self.predicates.visit_with(visitor)
686 }
687 }
688
689 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
690 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
691 match *self {
692 ty::Predicate::Trait(ref a) =>
693 ty::Predicate::Trait(a.fold_with(folder)),
694 ty::Predicate::Equate(ref binder) =>
695 ty::Predicate::Equate(binder.fold_with(folder)),
696 ty::Predicate::RegionOutlives(ref binder) =>
697 ty::Predicate::RegionOutlives(binder.fold_with(folder)),
698 ty::Predicate::TypeOutlives(ref binder) =>
699 ty::Predicate::TypeOutlives(binder.fold_with(folder)),
700 ty::Predicate::Projection(ref binder) =>
701 ty::Predicate::Projection(binder.fold_with(folder)),
702 ty::Predicate::WellFormed(data) =>
703 ty::Predicate::WellFormed(data.fold_with(folder)),
704 ty::Predicate::ClosureKind(closure_def_id, kind) =>
705 ty::Predicate::ClosureKind(closure_def_id, kind),
706 ty::Predicate::ObjectSafe(trait_def_id) =>
707 ty::Predicate::ObjectSafe(trait_def_id),
708 }
709 }
710
711 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
712 match *self {
713 ty::Predicate::Trait(ref a) => a.visit_with(visitor),
714 ty::Predicate::Equate(ref binder) => binder.visit_with(visitor),
715 ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
716 ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
717 ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
718 ty::Predicate::WellFormed(data) => data.visit_with(visitor),
719 ty::Predicate::ClosureKind(_closure_def_id, _kind) => false,
720 ty::Predicate::ObjectSafe(_trait_def_id) => false,
721 }
722 }
723 }
724
725 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
726 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
727 ty::ProjectionPredicate {
728 projection_ty: self.projection_ty.fold_with(folder),
729 ty: self.ty.fold_with(folder),
730 }
731 }
732
733 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
734 self.projection_ty.visit_with(visitor) || self.ty.visit_with(visitor)
735 }
736 }
737
738 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
739 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
740 ty::ExistentialProjection {
741 trait_ref: self.trait_ref.fold_with(folder),
742 item_name: self.item_name,
743 ty: self.ty.fold_with(folder),
744 }
745 }
746
747 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
748 self.trait_ref.visit_with(visitor) || self.ty.visit_with(visitor)
749 }
750 }
751
752 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
753 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
754 ty::ProjectionTy {
755 trait_ref: self.trait_ref.fold_with(folder),
756 item_name: self.item_name,
757 }
758 }
759
760 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
761 self.trait_ref.visit_with(visitor)
762 }
763 }
764
765 impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
766 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
767 ty::InstantiatedPredicates {
768 predicates: self.predicates.fold_with(folder),
769 }
770 }
771
772 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
773 self.predicates.visit_with(visitor)
774 }
775 }
776
777 impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> {
778 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
779 ty::EquatePredicate(self.0.fold_with(folder),
780 self.1.fold_with(folder))
781 }
782
783 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
784 self.0.visit_with(visitor) || self.1.visit_with(visitor)
785 }
786 }
787
788 impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
789 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
790 ty::TraitPredicate {
791 trait_ref: self.trait_ref.fold_with(folder)
792 }
793 }
794
795 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
796 self.trait_ref.visit_with(visitor)
797 }
798 }
799
800 impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
801 where T : TypeFoldable<'tcx>,
802 U : TypeFoldable<'tcx>,
803 {
804 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
805 ty::OutlivesPredicate(self.0.fold_with(folder),
806 self.1.fold_with(folder))
807 }
808
809 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
810 self.0.visit_with(visitor) || self.1.visit_with(visitor)
811 }
812 }
813
814 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
815 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
816 ty::ClosureUpvar {
817 def: self.def,
818 span: self.span,
819 ty: self.ty.fold_with(folder),
820 }
821 }
822
823 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
824 self.ty.visit_with(visitor)
825 }
826 }
827
828 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
829 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
830 ty::error::ExpectedFound {
831 expected: self.expected.fold_with(folder),
832 found: self.found.fold_with(folder),
833 }
834 }
835
836 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
837 self.expected.visit_with(visitor) || self.found.visit_with(visitor)
838 }
839 }
840
841 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
842 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
843 self.iter().map(|x| x.fold_with(folder)).collect()
844 }
845
846 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
847 self.iter().any(|t| t.visit_with(visitor))
848 }
849 }