]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/subst.rs
Remove `ReCanonical` in favor of `ReLateBound`
[rust.git] / src / librustc / ty / subst.rs
1 // Copyright 2012 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 // Type substitutions.
12
13 use hir::def_id::DefId;
14 use infer::canonical::Canonical;
15 use ty::{self, BoundVar, Lift, List, Ty, TyCtxt};
16 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
17
18 use serialize::{self, Encodable, Encoder, Decodable, Decoder};
19 use syntax_pos::{Span, DUMMY_SP};
20 use rustc_data_structures::indexed_vec::Idx;
21 use smallvec::SmallVec;
22
23 use core::intrinsics;
24 use std::cmp::Ordering;
25 use std::fmt;
26 use std::marker::PhantomData;
27 use std::mem;
28 use std::num::NonZeroUsize;
29
30 /// An entity in the Rust typesystem, which can be one of
31 /// several kinds (only types and lifetimes for now).
32 /// To reduce memory usage, a `Kind` is a interned pointer,
33 /// with the lowest 2 bits being reserved for a tag to
34 /// indicate the type (`Ty` or `Region`) it points to.
35 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
36 pub struct Kind<'tcx> {
37     ptr: NonZeroUsize,
38     marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)>
39 }
40
41 const TAG_MASK: usize = 0b11;
42 const TYPE_TAG: usize = 0b00;
43 const REGION_TAG: usize = 0b01;
44
45 #[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord)]
46 pub enum UnpackedKind<'tcx> {
47     Lifetime(ty::Region<'tcx>),
48     Type(Ty<'tcx>),
49 }
50
51 impl<'tcx> UnpackedKind<'tcx> {
52     fn pack(self) -> Kind<'tcx> {
53         let (tag, ptr) = match self {
54             UnpackedKind::Lifetime(lt) => {
55                 // Ensure we can use the tag bits.
56                 assert_eq!(mem::align_of_val(lt) & TAG_MASK, 0);
57                 (REGION_TAG, lt as *const _ as usize)
58             }
59             UnpackedKind::Type(ty) => {
60                 // Ensure we can use the tag bits.
61                 assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0);
62                 (TYPE_TAG, ty as *const _ as usize)
63             }
64         };
65
66         Kind {
67             ptr: unsafe {
68                 NonZeroUsize::new_unchecked(ptr | tag)
69             },
70             marker: PhantomData
71         }
72     }
73 }
74
75 impl<'tcx> Ord for Kind<'tcx> {
76     fn cmp(&self, other: &Kind<'_>) -> Ordering {
77         self.unpack().cmp(&other.unpack())
78     }
79 }
80
81 impl<'tcx> PartialOrd for Kind<'tcx> {
82     fn partial_cmp(&self, other: &Kind<'_>) -> Option<Ordering> {
83         Some(self.cmp(&other))
84     }
85 }
86
87 impl<'tcx> From<ty::Region<'tcx>> for Kind<'tcx> {
88     fn from(r: ty::Region<'tcx>) -> Kind<'tcx> {
89         UnpackedKind::Lifetime(r).pack()
90     }
91 }
92
93 impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
94     fn from(ty: Ty<'tcx>) -> Kind<'tcx> {
95         UnpackedKind::Type(ty).pack()
96     }
97 }
98
99 impl<'tcx> Kind<'tcx> {
100     #[inline]
101     pub fn unpack(self) -> UnpackedKind<'tcx> {
102         let ptr = self.ptr.get();
103         unsafe {
104             match ptr & TAG_MASK {
105                 REGION_TAG => UnpackedKind::Lifetime(&*((ptr & !TAG_MASK) as *const _)),
106                 TYPE_TAG => UnpackedKind::Type(&*((ptr & !TAG_MASK) as *const _)),
107                 _ => intrinsics::unreachable()
108             }
109         }
110     }
111 }
112
113 impl<'tcx> fmt::Debug for Kind<'tcx> {
114     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115         match self.unpack() {
116             UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt),
117             UnpackedKind::Type(ty) => write!(f, "{:?}", ty),
118         }
119     }
120 }
121
122 impl<'tcx> fmt::Display for Kind<'tcx> {
123     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124         match self.unpack() {
125             UnpackedKind::Lifetime(lt) => write!(f, "{}", lt),
126             UnpackedKind::Type(ty) => write!(f, "{}", ty),
127         }
128     }
129 }
130
131 impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
132     type Lifted = Kind<'tcx>;
133
134     fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option<Self::Lifted> {
135         match self.unpack() {
136             UnpackedKind::Lifetime(a) => a.lift_to_tcx(tcx).map(|a| a.into()),
137             UnpackedKind::Type(a) => a.lift_to_tcx(tcx).map(|a| a.into()),
138         }
139     }
140 }
141
142 impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> {
143     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
144         match self.unpack() {
145             UnpackedKind::Lifetime(lt) => lt.fold_with(folder).into(),
146             UnpackedKind::Type(ty) => ty.fold_with(folder).into(),
147         }
148     }
149
150     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
151         match self.unpack() {
152             UnpackedKind::Lifetime(lt) => lt.visit_with(visitor),
153             UnpackedKind::Type(ty) => ty.visit_with(visitor),
154         }
155     }
156 }
157
158 impl<'tcx> Encodable for Kind<'tcx> {
159     fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
160         self.unpack().encode(e)
161     }
162 }
163
164 impl<'tcx> Decodable for Kind<'tcx> {
165     fn decode<D: Decoder>(d: &mut D) -> Result<Kind<'tcx>, D::Error> {
166         Ok(UnpackedKind::decode(d)?.pack())
167     }
168 }
169
170 /// A substitution mapping generic parameters to new values.
171 pub type Substs<'tcx> = List<Kind<'tcx>>;
172
173 impl<'a, 'gcx, 'tcx> Substs<'tcx> {
174     /// Creates a Substs that maps each generic parameter to itself.
175     pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
176                              -> &'tcx Substs<'tcx> {
177         Substs::for_item(tcx, def_id, |param, _| {
178             tcx.mk_param_from_def(param)
179         })
180     }
181
182     /// Creates a Substs for generic parameter definitions,
183     /// by calling closures to obtain each kind.
184     /// The closures get to observe the Substs as they're
185     /// being built, which can be used to correctly
186     /// substitute defaults of generic parameters.
187     pub fn for_item<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
188                        def_id: DefId,
189                        mut mk_kind: F)
190                        -> &'tcx Substs<'tcx>
191     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
192     {
193         let defs = tcx.generics_of(def_id);
194         let count = defs.count();
195         let mut substs = SmallVec::with_capacity(count);
196         Substs::fill_item(&mut substs, tcx, defs, &mut mk_kind);
197         tcx.intern_substs(&substs)
198     }
199
200     pub fn extend_to<F>(&self,
201                         tcx: TyCtxt<'a, 'gcx, 'tcx>,
202                         def_id: DefId,
203                         mut mk_kind: F)
204                         -> &'tcx Substs<'tcx>
205     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
206     {
207         Substs::for_item(tcx, def_id, |param, substs| {
208             self.get(param.index as usize)
209                 .cloned()
210                 .unwrap_or_else(|| mk_kind(param, substs))
211         })
212     }
213
214     fn fill_item<F>(substs: &mut SmallVec<[Kind<'tcx>; 8]>,
215                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
216                     defs: &ty::Generics,
217                     mk_kind: &mut F)
218     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
219     {
220         if let Some(def_id) = defs.parent {
221             let parent_defs = tcx.generics_of(def_id);
222             Substs::fill_item(substs, tcx, parent_defs, mk_kind);
223         }
224         Substs::fill_single(substs, defs, mk_kind)
225     }
226
227     fn fill_single<F>(substs: &mut SmallVec<[Kind<'tcx>; 8]>,
228                       defs: &ty::Generics,
229                       mk_kind: &mut F)
230     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
231     {
232         substs.reserve(defs.params.len());
233         for param in &defs.params {
234             let kind = mk_kind(param, substs);
235             assert_eq!(param.index as usize, substs.len());
236             substs.push(kind);
237         }
238     }
239
240     pub fn is_noop(&self) -> bool {
241         self.is_empty()
242     }
243
244     #[inline]
245     pub fn types(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
246         self.iter().filter_map(|k| {
247             if let UnpackedKind::Type(ty) = k.unpack() {
248                 Some(ty)
249             } else {
250                 None
251             }
252         })
253     }
254
255     #[inline]
256     pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=ty::Region<'tcx>> + 'a {
257         self.iter().filter_map(|k| {
258             if let UnpackedKind::Lifetime(lt) = k.unpack() {
259                 Some(lt)
260             } else {
261                 None
262             }
263         })
264     }
265
266     #[inline]
267     pub fn type_at(&self, i: usize) -> Ty<'tcx> {
268         if let UnpackedKind::Type(ty) = self[i].unpack() {
269             ty
270         } else {
271             bug!("expected type for param #{} in {:?}", i, self);
272         }
273     }
274
275     #[inline]
276     pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
277         if let UnpackedKind::Lifetime(lt) = self[i].unpack() {
278             lt
279         } else {
280             bug!("expected region for param #{} in {:?}", i, self);
281         }
282     }
283
284     #[inline]
285     pub fn type_for_def(&self, def: &ty::GenericParamDef) -> Kind<'tcx> {
286         self.type_at(def.index as usize).into()
287     }
288
289     /// Transform from substitutions for a child of `source_ancestor`
290     /// (e.g. a trait or impl) to substitutions for the same child
291     /// in a different item, with `target_substs` as the base for
292     /// the target impl/trait, with the source child-specific
293     /// parameters (e.g. method parameters) on top of that base.
294     pub fn rebase_onto(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
295                        source_ancestor: DefId,
296                        target_substs: &Substs<'tcx>)
297                        -> &'tcx Substs<'tcx> {
298         let defs = tcx.generics_of(source_ancestor);
299         tcx.mk_substs(target_substs.iter().chain(&self[defs.params.len()..]).cloned())
300     }
301
302     pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics)
303                        -> &'tcx Substs<'tcx> {
304         tcx.mk_substs(self.iter().take(generics.count()).cloned())
305     }
306 }
307
308 impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
309     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
310         let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
311
312         // If folding doesn't change the substs, it's faster to avoid
313         // calling `mk_substs` and instead reuse the existing substs.
314         if params[..] == self[..] {
315             self
316         } else {
317             folder.tcx().intern_substs(&params)
318         }
319     }
320
321     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
322         self.iter().any(|t| t.visit_with(visitor))
323     }
324 }
325
326 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
327
328 ///////////////////////////////////////////////////////////////////////////
329 // Public trait `Subst`
330 //
331 // Just call `foo.subst(tcx, substs)` to perform a substitution across
332 // `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
333 // there is more information available (for better errors).
334
335 pub trait Subst<'tcx> : Sized {
336     fn subst<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
337                        substs: &[Kind<'tcx>]) -> Self {
338         self.subst_spanned(tcx, substs, None)
339     }
340
341     fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
342                                substs: &[Kind<'tcx>],
343                                span: Option<Span>)
344                                -> Self;
345 }
346
347 impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
348     fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
349                                substs: &[Kind<'tcx>],
350                                span: Option<Span>)
351                                -> T
352     {
353         let mut folder = SubstFolder { tcx,
354                                        substs,
355                                        span,
356                                        root_ty: None,
357                                        ty_stack_depth: 0,
358                                        binders_passed: 0 };
359         (*self).fold_with(&mut folder)
360     }
361 }
362
363 ///////////////////////////////////////////////////////////////////////////
364 // The actual substitution engine itself is a type folder.
365
366 struct SubstFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
367     tcx: TyCtxt<'a, 'gcx, 'tcx>,
368     substs: &'a [Kind<'tcx>],
369
370     // The location for which the substitution is performed, if available.
371     span: Option<Span>,
372
373     // The root type that is being substituted, if available.
374     root_ty: Option<Ty<'tcx>>,
375
376     // Depth of type stack
377     ty_stack_depth: usize,
378
379     // Number of region binders we have passed through while doing the substitution
380     binders_passed: u32,
381 }
382
383 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
384     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
385
386     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
387         self.binders_passed += 1;
388         let t = t.super_fold_with(self);
389         self.binders_passed -= 1;
390         t
391     }
392
393     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
394         // Note: This routine only handles regions that are bound on
395         // type declarations and other outer declarations, not those
396         // bound in *fn types*. Region substitution of the bound
397         // regions that appear in a function signature is done using
398         // the specialized routine `ty::replace_late_regions()`.
399         match *r {
400             ty::ReEarlyBound(data) => {
401                 let r = self.substs.get(data.index as usize).map(|k| k.unpack());
402                 match r {
403                     Some(UnpackedKind::Lifetime(lt)) => {
404                         self.shift_region_through_binders(lt)
405                     }
406                     _ => {
407                         let span = self.span.unwrap_or(DUMMY_SP);
408                         span_bug!(
409                             span,
410                             "Region parameter out of range \
411                              when substituting in region {} (root type={:?}) \
412                              (index={})",
413                             data.name,
414                             self.root_ty,
415                             data.index);
416                     }
417                 }
418             }
419             _ => r
420         }
421     }
422
423     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
424         if !t.needs_subst() {
425             return t;
426         }
427
428         // track the root type we were asked to substitute
429         let depth = self.ty_stack_depth;
430         if depth == 0 {
431             self.root_ty = Some(t);
432         }
433         self.ty_stack_depth += 1;
434
435         let t1 = match t.sty {
436             ty::Param(p) => {
437                 self.ty_for_param(p, t)
438             }
439             _ => {
440                 t.super_fold_with(self)
441             }
442         };
443
444         assert_eq!(depth + 1, self.ty_stack_depth);
445         self.ty_stack_depth -= 1;
446         if depth == 0 {
447             self.root_ty = None;
448         }
449
450         return t1;
451     }
452 }
453
454 impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
455     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
456         // Look up the type in the substitutions. It really should be in there.
457         let opt_ty = self.substs.get(p.idx as usize).map(|k| k.unpack());
458         let ty = match opt_ty {
459             Some(UnpackedKind::Type(ty)) => ty,
460             _ => {
461                 let span = self.span.unwrap_or(DUMMY_SP);
462                 span_bug!(
463                     span,
464                     "Type parameter `{:?}` ({:?}/{}) out of range \
465                      when substituting (root type={:?}) substs={:?}",
466                     p,
467                     source_ty,
468                     p.idx,
469                     self.root_ty,
470                     self.substs);
471             }
472         };
473
474         self.shift_vars_through_binders(ty)
475     }
476
477     /// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
478     /// when we are substituting a type with escaping bound vars into a context where we have
479     /// passed through binders. That's quite a mouthful. Let's see an example:
480     ///
481     /// ```
482     /// type Func<A> = fn(A);
483     /// type MetaFunc = for<'a> fn(Func<&'a int>)
484     /// ```
485     ///
486     /// The type `MetaFunc`, when fully expanded, will be
487     ///
488     ///     for<'a> fn(fn(&'a int))
489     ///             ^~ ^~ ^~~
490     ///             |  |  |
491     ///             |  |  DebruijnIndex of 2
492     ///             Binders
493     ///
494     /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
495     /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
496     /// over the inner binder (remember that we count Debruijn indices from 1). However, in the
497     /// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a
498     /// debruijn index of 1. It's only during the substitution that we can see we must increase the
499     /// depth by 1 to account for the binder that we passed through.
500     ///
501     /// As a second example, consider this twist:
502     ///
503     /// ```
504     /// type FuncTuple<A> = (A,fn(A));
505     /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>)
506     /// ```
507     ///
508     /// Here the final type will be:
509     ///
510     ///     for<'a> fn((&'a int, fn(&'a int)))
511     ///                 ^~~         ^~~
512     ///                 |           |
513     ///          DebruijnIndex of 1 |
514     ///                      DebruijnIndex of 2
515     ///
516     /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
517     /// first case we do not increase the Debruijn index and in the second case we do. The reason
518     /// is that only in the second case have we passed through a fn binder.
519     fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
520         debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
521                ty, self.binders_passed, ty.has_escaping_bound_vars());
522
523         if self.binders_passed == 0 || !ty.has_escaping_bound_vars() {
524             return ty;
525         }
526
527         let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
528         debug!("shift_vars: shifted result = {:?}", result);
529
530         result
531     }
532
533     fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
534         if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
535             return region;
536         }
537         ty::fold::shift_region(self.tcx, region, self.binders_passed)
538     }
539 }
540
541 pub type CanonicalUserSubsts<'tcx> = Canonical<'tcx, UserSubsts<'tcx>>;
542
543 impl CanonicalUserSubsts<'tcx> {
544     /// True if this represents a substitution like
545     ///
546     /// ```text
547     /// [?0, ?1, ?2]
548     /// ```
549     ///
550     /// i.e., each thing is mapped to a canonical variable with the same index.
551     pub fn is_identity(&self) -> bool {
552         if self.value.user_self_ty.is_some() {
553             return false;
554         }
555
556         self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
557             match kind.unpack() {
558                 UnpackedKind::Type(ty) => match ty.sty {
559                     ty::Bound(b) => {
560                         // We only allow a `ty::INNERMOST` index in substitutions.
561                         assert_eq!(b.index, ty::INNERMOST);
562                         cvar == b.var
563                     }
564                     _ => false,
565                 },
566
567                 UnpackedKind::Lifetime(r) => match r {
568                     ty::ReLateBound(index, br) => {
569                         // We only allow a `ty::INNERMOST` index in substitutions.
570                         assert_eq!(*index, ty::INNERMOST);
571                         cvar == br.as_bound_var()
572                     }
573                     _ => false,
574                 },
575             }
576         })
577     }
578 }
579
580 /// Stores the user-given substs to reach some fully qualified path
581 /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
582 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
583 pub struct UserSubsts<'tcx> {
584     /// The substitutions for the item as given by the user.
585     pub substs: &'tcx Substs<'tcx>,
586
587     /// The self-type, in the case of a `<T>::Item` path (when applied
588     /// to an inherent impl). See `UserSelfTy` below.
589     pub user_self_ty: Option<UserSelfTy<'tcx>>,
590 }
591
592 BraceStructTypeFoldableImpl! {
593     impl<'tcx> TypeFoldable<'tcx> for UserSubsts<'tcx> {
594         substs,
595         user_self_ty,
596     }
597 }
598
599 BraceStructLiftImpl! {
600     impl<'a, 'tcx> Lift<'tcx> for UserSubsts<'a> {
601         type Lifted = UserSubsts<'tcx>;
602         substs,
603         user_self_ty,
604     }
605 }
606
607 /// Specifies the user-given self-type. In the case of a path that
608 /// refers to a member in an inherent impl, this self-type is
609 /// sometimes needed to constrain the type parameters on the impl. For
610 /// example, in this code:
611 ///
612 /// ```
613 /// struct Foo<T> { }
614 /// impl<A> Foo<A> { fn method() { } }
615 /// ```
616 ///
617 /// when you then have a path like `<Foo<&'static u32>>::method`,
618 /// this struct would carry the def-id of the impl along with the
619 /// self-type `Foo<u32>`. Then we can instantiate the parameters of
620 /// the impl (with the substs from `UserSubsts`) and apply those to
621 /// the self-type, giving `Foo<?A>`. Finally, we unify that with
622 /// the self-type here, which contains `?A` to be `&'static u32`
623 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
624 pub struct UserSelfTy<'tcx> {
625     pub impl_def_id: DefId,
626     pub self_ty: Ty<'tcx>,
627 }
628
629 BraceStructTypeFoldableImpl! {
630     impl<'tcx> TypeFoldable<'tcx> for UserSelfTy<'tcx> {
631         impl_def_id,
632         self_ty,
633     }
634 }
635
636 BraceStructLiftImpl! {
637     impl<'a, 'tcx> Lift<'tcx> for UserSelfTy<'a> {
638         type Lifted = UserSelfTy<'tcx>;
639         impl_def_id,
640         self_ty,
641     }
642 }