]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/subst.rs
Various minor/cosmetic improvements to code
[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 type system, 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` that maps each generic parameter to a higher-ranked
183     /// var bound at index `0`. For types, we use a `BoundVar` index equal to
184     /// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
185     /// variant (which has a def-id).
186     pub fn bound_vars_for_item(
187         tcx: TyCtxt<'a, 'gcx, 'tcx>,
188         def_id: DefId
189     ) -> &'tcx Substs<'tcx> {
190         Substs::for_item(tcx, def_id, |param, _| {
191             match param.kind {
192                 ty::GenericParamDefKind::Type { .. } => {
193                     tcx.mk_ty(
194                         ty::Bound(ty::INNERMOST, ty::BoundTy {
195                             var: ty::BoundVar::from(param.index),
196                             kind: ty::BoundTyKind::Param(param.name),
197                         })
198                     ).into()
199                 }
200
201                 ty::GenericParamDefKind::Lifetime => {
202                     tcx.mk_region(ty::RegionKind::ReLateBound(
203                         ty::INNERMOST,
204                         ty::BoundRegion::BrNamed(param.def_id, param.name)
205                     )).into()
206                 }
207             }
208         })
209     }
210
211     /// Creates a `Substs` for generic parameter definitions,
212     /// by calling closures to obtain each kind.
213     /// The closures get to observe the `Substs` as they're
214     /// being built, which can be used to correctly
215     /// substitute defaults of generic parameters.
216     pub fn for_item<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
217                        def_id: DefId,
218                        mut mk_kind: F)
219                        -> &'tcx Substs<'tcx>
220     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
221     {
222         let defs = tcx.generics_of(def_id);
223         let count = defs.count();
224         let mut substs = SmallVec::with_capacity(count);
225         Substs::fill_item(&mut substs, tcx, defs, &mut mk_kind);
226         tcx.intern_substs(&substs)
227     }
228
229     pub fn extend_to<F>(&self,
230                         tcx: TyCtxt<'a, 'gcx, 'tcx>,
231                         def_id: DefId,
232                         mut mk_kind: F)
233                         -> &'tcx Substs<'tcx>
234     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
235     {
236         Substs::for_item(tcx, def_id, |param, substs| {
237             self.get(param.index as usize)
238                 .cloned()
239                 .unwrap_or_else(|| mk_kind(param, substs))
240         })
241     }
242
243     fn fill_item<F>(substs: &mut SmallVec<[Kind<'tcx>; 8]>,
244                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
245                     defs: &ty::Generics,
246                     mk_kind: &mut F)
247     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
248     {
249         if let Some(def_id) = defs.parent {
250             let parent_defs = tcx.generics_of(def_id);
251             Substs::fill_item(substs, tcx, parent_defs, mk_kind);
252         }
253         Substs::fill_single(substs, defs, mk_kind)
254     }
255
256     fn fill_single<F>(substs: &mut SmallVec<[Kind<'tcx>; 8]>,
257                       defs: &ty::Generics,
258                       mk_kind: &mut F)
259     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
260     {
261         substs.reserve(defs.params.len());
262         for param in &defs.params {
263             let kind = mk_kind(param, substs);
264             assert_eq!(param.index as usize, substs.len());
265             substs.push(kind);
266         }
267     }
268
269     pub fn is_noop(&self) -> bool {
270         self.is_empty()
271     }
272
273     #[inline]
274     pub fn types(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
275         self.iter().filter_map(|k| {
276             if let UnpackedKind::Type(ty) = k.unpack() {
277                 Some(ty)
278             } else {
279                 None
280             }
281         })
282     }
283
284     #[inline]
285     pub fn regions(&'a self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'a {
286         self.iter().filter_map(|k| {
287             if let UnpackedKind::Lifetime(lt) = k.unpack() {
288                 Some(lt)
289             } else {
290                 None
291             }
292         })
293     }
294
295     #[inline]
296     pub fn type_at(&self, i: usize) -> Ty<'tcx> {
297         if let UnpackedKind::Type(ty) = self[i].unpack() {
298             ty
299         } else {
300             bug!("expected type for param #{} in {:?}", i, self);
301         }
302     }
303
304     #[inline]
305     pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
306         if let UnpackedKind::Lifetime(lt) = self[i].unpack() {
307             lt
308         } else {
309             bug!("expected region for param #{} in {:?}", i, self);
310         }
311     }
312
313     #[inline]
314     pub fn type_for_def(&self, def: &ty::GenericParamDef) -> Kind<'tcx> {
315         self.type_at(def.index as usize).into()
316     }
317
318     /// Transform from substitutions for a child of `source_ancestor`
319     /// (e.g., a trait or impl) to substitutions for the same child
320     /// in a different item, with `target_substs` as the base for
321     /// the target impl/trait, with the source child-specific
322     /// parameters (e.g., method parameters) on top of that base.
323     pub fn rebase_onto(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
324                        source_ancestor: DefId,
325                        target_substs: &Substs<'tcx>)
326                        -> &'tcx Substs<'tcx> {
327         let defs = tcx.generics_of(source_ancestor);
328         tcx.mk_substs(target_substs.iter().chain(&self[defs.params.len()..]).cloned())
329     }
330
331     pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics)
332                        -> &'tcx Substs<'tcx> {
333         tcx.mk_substs(self.iter().take(generics.count()).cloned())
334     }
335 }
336
337 impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
338     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
339         let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
340
341         // If folding doesn't change the substs, it's faster to avoid
342         // calling `mk_substs` and instead reuse the existing substs.
343         if params[..] == self[..] {
344             self
345         } else {
346             folder.tcx().intern_substs(&params)
347         }
348     }
349
350     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
351         self.iter().any(|t| t.visit_with(visitor))
352     }
353 }
354
355 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
356
357 ///////////////////////////////////////////////////////////////////////////
358 // Public trait `Subst`
359 //
360 // Just call `foo.subst(tcx, substs)` to perform a substitution across
361 // `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
362 // there is more information available (for better errors).
363
364 pub trait Subst<'tcx>: Sized {
365     fn subst<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
366                        substs: &[Kind<'tcx>]) -> Self {
367         self.subst_spanned(tcx, substs, None)
368     }
369
370     fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
371                                substs: &[Kind<'tcx>],
372                                span: Option<Span>)
373                                -> Self;
374 }
375
376 impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
377     fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
378                                substs: &[Kind<'tcx>],
379                                span: Option<Span>)
380                                -> T
381     {
382         let mut folder = SubstFolder { tcx,
383                                        substs,
384                                        span,
385                                        root_ty: None,
386                                        ty_stack_depth: 0,
387                                        binders_passed: 0 };
388         (*self).fold_with(&mut folder)
389     }
390 }
391
392 ///////////////////////////////////////////////////////////////////////////
393 // The actual substitution engine itself is a type folder.
394
395 struct SubstFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
396     tcx: TyCtxt<'a, 'gcx, 'tcx>,
397     substs: &'a [Kind<'tcx>],
398
399     // The location for which the substitution is performed, if available.
400     span: Option<Span>,
401
402     // The root type that is being substituted, if available.
403     root_ty: Option<Ty<'tcx>>,
404
405     // Depth of type stack
406     ty_stack_depth: usize,
407
408     // Number of region binders we have passed through while doing the substitution
409     binders_passed: u32,
410 }
411
412 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
413     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
414
415     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
416         self.binders_passed += 1;
417         let t = t.super_fold_with(self);
418         self.binders_passed -= 1;
419         t
420     }
421
422     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
423         // Note: This routine only handles regions that are bound on
424         // type declarations and other outer declarations, not those
425         // bound in *fn types*. Region substitution of the bound
426         // regions that appear in a function signature is done using
427         // the specialized routine `ty::replace_late_regions()`.
428         match *r {
429             ty::ReEarlyBound(data) => {
430                 let r = self.substs.get(data.index as usize).map(|k| k.unpack());
431                 match r {
432                     Some(UnpackedKind::Lifetime(lt)) => {
433                         self.shift_region_through_binders(lt)
434                     }
435                     _ => {
436                         let span = self.span.unwrap_or(DUMMY_SP);
437                         span_bug!(
438                             span,
439                             "Region parameter out of range \
440                              when substituting in region {} (root type={:?}) \
441                              (index={})",
442                             data.name,
443                             self.root_ty,
444                             data.index);
445                     }
446                 }
447             }
448             _ => r
449         }
450     }
451
452     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
453         if !t.needs_subst() {
454             return t;
455         }
456
457         // track the root type we were asked to substitute
458         let depth = self.ty_stack_depth;
459         if depth == 0 {
460             self.root_ty = Some(t);
461         }
462         self.ty_stack_depth += 1;
463
464         let t1 = match t.sty {
465             ty::Param(p) => {
466                 self.ty_for_param(p, t)
467             }
468             _ => {
469                 t.super_fold_with(self)
470             }
471         };
472
473         assert_eq!(depth + 1, self.ty_stack_depth);
474         self.ty_stack_depth -= 1;
475         if depth == 0 {
476             self.root_ty = None;
477         }
478
479         return t1;
480     }
481 }
482
483 impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
484     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
485         // Look up the type in the substitutions. It really should be in there.
486         let opt_ty = self.substs.get(p.idx as usize).map(|k| k.unpack());
487         let ty = match opt_ty {
488             Some(UnpackedKind::Type(ty)) => ty,
489             _ => {
490                 let span = self.span.unwrap_or(DUMMY_SP);
491                 span_bug!(
492                     span,
493                     "Type parameter `{:?}` ({:?}/{}) out of range \
494                      when substituting (root type={:?}) substs={:?}",
495                     p,
496                     source_ty,
497                     p.idx,
498                     self.root_ty,
499                     self.substs);
500             }
501         };
502
503         self.shift_vars_through_binders(ty)
504     }
505
506     /// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
507     /// when we are substituting a type with escaping bound vars into a context where we have
508     /// passed through binders. That's quite a mouthful. Let's see an example:
509     ///
510     /// ```
511     /// type Func<A> = fn(A);
512     /// type MetaFunc = for<'a> fn(Func<&'a int>)
513     /// ```
514     ///
515     /// The type `MetaFunc`, when fully expanded, will be
516     ///
517     ///     for<'a> fn(fn(&'a int))
518     ///             ^~ ^~ ^~~
519     ///             |  |  |
520     ///             |  |  DebruijnIndex of 2
521     ///             Binders
522     ///
523     /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
524     /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
525     /// over the inner binder (remember that we count Debruijn indices from 1). However, in the
526     /// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a
527     /// debruijn index of 1. It's only during the substitution that we can see we must increase the
528     /// depth by 1 to account for the binder that we passed through.
529     ///
530     /// As a second example, consider this twist:
531     ///
532     /// ```
533     /// type FuncTuple<A> = (A,fn(A));
534     /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>)
535     /// ```
536     ///
537     /// Here the final type will be:
538     ///
539     ///     for<'a> fn((&'a int, fn(&'a int)))
540     ///                 ^~~         ^~~
541     ///                 |           |
542     ///          DebruijnIndex of 1 |
543     ///                      DebruijnIndex of 2
544     ///
545     /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
546     /// first case we do not increase the Debruijn index and in the second case we do. The reason
547     /// is that only in the second case have we passed through a fn binder.
548     fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
549         debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
550                ty, self.binders_passed, ty.has_escaping_bound_vars());
551
552         if self.binders_passed == 0 || !ty.has_escaping_bound_vars() {
553             return ty;
554         }
555
556         let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
557         debug!("shift_vars: shifted result = {:?}", result);
558
559         result
560     }
561
562     fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
563         if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
564             return region;
565         }
566         ty::fold::shift_region(self.tcx, region, self.binders_passed)
567     }
568 }
569
570 pub type CanonicalUserSubsts<'tcx> = Canonical<'tcx, UserSubsts<'tcx>>;
571
572 impl CanonicalUserSubsts<'tcx> {
573     /// True if this represents a substitution like
574     ///
575     /// ```text
576     /// [?0, ?1, ?2]
577     /// ```
578     ///
579     /// i.e., each thing is mapped to a canonical variable with the same index.
580     pub fn is_identity(&self) -> bool {
581         if self.value.user_self_ty.is_some() {
582             return false;
583         }
584
585         self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
586             match kind.unpack() {
587                 UnpackedKind::Type(ty) => match ty.sty {
588                     ty::Bound(debruijn, b) => {
589                         // We only allow a `ty::INNERMOST` index in substitutions.
590                         assert_eq!(debruijn, ty::INNERMOST);
591                         cvar == b.var
592                     }
593                     _ => false,
594                 },
595
596                 UnpackedKind::Lifetime(r) => match r {
597                     ty::ReLateBound(debruijn, br) => {
598                         // We only allow a `ty::INNERMOST` index in substitutions.
599                         assert_eq!(*debruijn, ty::INNERMOST);
600                         cvar == br.assert_bound_var()
601                     }
602                     _ => false,
603                 },
604             }
605         })
606     }
607 }
608
609 /// Stores the user-given substs to reach some fully qualified path
610 /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
611 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
612 pub struct UserSubsts<'tcx> {
613     /// The substitutions for the item as given by the user.
614     pub substs: &'tcx Substs<'tcx>,
615
616     /// The self-type, in the case of a `<T>::Item` path (when applied
617     /// to an inherent impl). See `UserSelfTy` below.
618     pub user_self_ty: Option<UserSelfTy<'tcx>>,
619 }
620
621 BraceStructTypeFoldableImpl! {
622     impl<'tcx> TypeFoldable<'tcx> for UserSubsts<'tcx> {
623         substs,
624         user_self_ty,
625     }
626 }
627
628 BraceStructLiftImpl! {
629     impl<'a, 'tcx> Lift<'tcx> for UserSubsts<'a> {
630         type Lifted = UserSubsts<'tcx>;
631         substs,
632         user_self_ty,
633     }
634 }
635
636 /// Specifies the user-given self-type. In the case of a path that
637 /// refers to a member in an inherent impl, this self-type is
638 /// sometimes needed to constrain the type parameters on the impl. For
639 /// example, in this code:
640 ///
641 /// ```
642 /// struct Foo<T> { }
643 /// impl<A> Foo<A> { fn method() { } }
644 /// ```
645 ///
646 /// when you then have a path like `<Foo<&'static u32>>::method`,
647 /// this struct would carry the def-id of the impl along with the
648 /// self-type `Foo<u32>`. Then we can instantiate the parameters of
649 /// the impl (with the substs from `UserSubsts`) and apply those to
650 /// the self-type, giving `Foo<?A>`. Finally, we unify that with
651 /// the self-type here, which contains `?A` to be `&'static u32`
652 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
653 pub struct UserSelfTy<'tcx> {
654     pub impl_def_id: DefId,
655     pub self_ty: Ty<'tcx>,
656 }
657
658 BraceStructTypeFoldableImpl! {
659     impl<'tcx> TypeFoldable<'tcx> for UserSelfTy<'tcx> {
660         impl_def_id,
661         self_ty,
662     }
663 }
664
665 BraceStructLiftImpl! {
666     impl<'a, 'tcx> Lift<'tcx> for UserSelfTy<'a> {
667         type Lifted = UserSelfTy<'tcx>;
668         impl_def_id,
669         self_ty,
670     }
671 }