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