3 use crate::ty
::codec
::{TyDecoder, TyEncoder}
;
4 use crate::ty
::fold
::{TypeFoldable, TypeFolder, TypeVisitor}
;
5 use crate::ty
::sty
::{ClosureSubsts, GeneratorSubsts}
;
6 use crate::ty
::{self, Lift, List, ParamConst, Ty, TyCtxt}
;
8 use rustc_hir
::def_id
::DefId
;
9 use rustc_macros
::HashStable
;
10 use rustc_serialize
::{self, Decodable, Encodable}
;
11 use rustc_span
::{Span, DUMMY_SP}
;
12 use smallvec
::SmallVec
;
15 use std
::cmp
::Ordering
;
17 use std
::marker
::PhantomData
;
19 use std
::num
::NonZeroUsize
;
20 use std
::ops
::ControlFlow
;
22 /// An entity in the Rust type system, which can be one of
23 /// several kinds (types, lifetimes, and consts).
24 /// To reduce memory usage, a `GenericArg` is a interned pointer,
25 /// with the lowest 2 bits being reserved for a tag to
26 /// indicate the type (`Ty`, `Region`, or `Const`) it points to.
27 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
28 pub struct GenericArg
<'tcx
> {
30 marker
: PhantomData
<(Ty
<'tcx
>, ty
::Region
<'tcx
>, &'tcx ty
::Const
<'tcx
>)>,
33 const TAG_MASK
: usize = 0b11;
34 const TYPE_TAG
: usize = 0b00;
35 const REGION_TAG
: usize = 0b01;
36 const CONST_TAG
: usize = 0b10;
38 #[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
39 pub enum GenericArgKind
<'tcx
> {
40 Lifetime(ty
::Region
<'tcx
>),
42 Const(&'tcx ty
::Const
<'tcx
>),
45 impl<'tcx
> GenericArgKind
<'tcx
> {
46 fn pack(self) -> GenericArg
<'tcx
> {
47 let (tag
, ptr
) = match self {
48 GenericArgKind
::Lifetime(lt
) => {
49 // Ensure we can use the tag bits.
50 assert_eq
!(mem
::align_of_val(lt
) & TAG_MASK
, 0);
51 (REGION_TAG
, lt
as *const _
as usize)
53 GenericArgKind
::Type(ty
) => {
54 // Ensure we can use the tag bits.
55 assert_eq
!(mem
::align_of_val(ty
) & TAG_MASK
, 0);
56 (TYPE_TAG
, ty
as *const _
as usize)
58 GenericArgKind
::Const(ct
) => {
59 // Ensure we can use the tag bits.
60 assert_eq
!(mem
::align_of_val(ct
) & TAG_MASK
, 0);
61 (CONST_TAG
, ct
as *const _
as usize)
65 GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }
, marker
: PhantomData
}
69 impl fmt
::Debug
for GenericArg
<'tcx
> {
70 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
72 GenericArgKind
::Lifetime(lt
) => lt
.fmt(f
),
73 GenericArgKind
::Type(ty
) => ty
.fmt(f
),
74 GenericArgKind
::Const(ct
) => ct
.fmt(f
),
79 impl<'tcx
> Ord
for GenericArg
<'tcx
> {
80 fn cmp(&self, other
: &GenericArg
<'_
>) -> Ordering
{
81 self.unpack().cmp(&other
.unpack())
85 impl<'tcx
> PartialOrd
for GenericArg
<'tcx
> {
86 fn partial_cmp(&self, other
: &GenericArg
<'_
>) -> Option
<Ordering
> {
87 Some(self.cmp(&other
))
91 impl<'tcx
> From
<ty
::Region
<'tcx
>> for GenericArg
<'tcx
> {
92 fn from(r
: ty
::Region
<'tcx
>) -> GenericArg
<'tcx
> {
93 GenericArgKind
::Lifetime(r
).pack()
97 impl<'tcx
> From
<Ty
<'tcx
>> for GenericArg
<'tcx
> {
98 fn from(ty
: Ty
<'tcx
>) -> GenericArg
<'tcx
> {
99 GenericArgKind
::Type(ty
).pack()
103 impl<'tcx
> From
<&'tcx ty
::Const
<'tcx
>> for GenericArg
<'tcx
> {
104 fn from(c
: &'tcx ty
::Const
<'tcx
>) -> GenericArg
<'tcx
> {
105 GenericArgKind
::Const(c
).pack()
109 impl<'tcx
> GenericArg
<'tcx
> {
111 pub fn unpack(self) -> GenericArgKind
<'tcx
> {
112 let ptr
= self.ptr
.get();
114 match ptr
& TAG_MASK
{
115 REGION_TAG
=> GenericArgKind
::Lifetime(&*((ptr
& !TAG_MASK
) as *const _
)),
116 TYPE_TAG
=> GenericArgKind
::Type(&*((ptr
& !TAG_MASK
) as *const _
)),
117 CONST_TAG
=> GenericArgKind
::Const(&*((ptr
& !TAG_MASK
) as *const _
)),
118 _
=> intrinsics
::unreachable(),
123 /// Unpack the `GenericArg` as a type when it is known certainly to be a type.
124 /// This is true in cases where `Substs` is used in places where the kinds are known
125 /// to be limited (e.g. in tuples, where the only parameters are type parameters).
126 pub fn expect_ty(self) -> Ty
<'tcx
> {
127 match self.unpack() {
128 GenericArgKind
::Type(ty
) => ty
,
129 _
=> bug
!("expected a type, but found another kind"),
133 /// Unpack the `GenericArg` as a const when it is known certainly to be a const.
134 pub fn expect_const(self) -> &'tcx ty
::Const
<'tcx
> {
135 match self.unpack() {
136 GenericArgKind
::Const(c
) => c
,
137 _
=> bug
!("expected a const, but found another kind"),
142 impl<'a
, 'tcx
> Lift
<'tcx
> for GenericArg
<'a
> {
143 type Lifted
= GenericArg
<'tcx
>;
145 fn lift_to_tcx(self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
146 match self.unpack() {
147 GenericArgKind
::Lifetime(lt
) => tcx
.lift(lt
).map(|lt
| lt
.into()),
148 GenericArgKind
::Type(ty
) => tcx
.lift(ty
).map(|ty
| ty
.into()),
149 GenericArgKind
::Const(ct
) => tcx
.lift(ct
).map(|ct
| ct
.into()),
154 impl<'tcx
> TypeFoldable
<'tcx
> for GenericArg
<'tcx
> {
155 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
156 match self.unpack() {
157 GenericArgKind
::Lifetime(lt
) => lt
.fold_with(folder
).into(),
158 GenericArgKind
::Type(ty
) => ty
.fold_with(folder
).into(),
159 GenericArgKind
::Const(ct
) => ct
.fold_with(folder
).into(),
163 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
164 match self.unpack() {
165 GenericArgKind
::Lifetime(lt
) => lt
.visit_with(visitor
),
166 GenericArgKind
::Type(ty
) => ty
.visit_with(visitor
),
167 GenericArgKind
::Const(ct
) => ct
.visit_with(visitor
),
172 impl<'tcx
, E
: TyEncoder
<'tcx
>> Encodable
<E
> for GenericArg
<'tcx
> {
173 fn encode(&self, e
: &mut E
) -> Result
<(), E
::Error
> {
174 self.unpack().encode(e
)
178 impl<'tcx
, D
: TyDecoder
<'tcx
>> Decodable
<D
> for GenericArg
<'tcx
> {
179 fn decode(d
: &mut D
) -> Result
<GenericArg
<'tcx
>, D
::Error
> {
180 Ok(GenericArgKind
::decode(d
)?
.pack())
184 /// A substitution mapping generic parameters to new values.
185 pub type InternalSubsts
<'tcx
> = List
<GenericArg
<'tcx
>>;
187 pub type SubstsRef
<'tcx
> = &'tcx InternalSubsts
<'tcx
>;
189 impl<'a
, 'tcx
> InternalSubsts
<'tcx
> {
190 /// Interpret these substitutions as the substitutions of a closure type.
191 /// Closure substitutions have a particular structure controlled by the
192 /// compiler that encodes information like the signature and closure kind;
193 /// see `ty::ClosureSubsts` struct for more comments.
194 pub fn as_closure(&'a
self) -> ClosureSubsts
<'a
> {
195 ClosureSubsts { substs: self }
198 /// Interpret these substitutions as the substitutions of a generator type.
199 /// Closure substitutions have a particular structure controlled by the
200 /// compiler that encodes information like the signature and generator kind;
201 /// see `ty::GeneratorSubsts` struct for more comments.
202 pub fn as_generator(&'tcx
self) -> GeneratorSubsts
<'tcx
> {
203 GeneratorSubsts { substs: self }
206 /// Creates a `InternalSubsts` that maps each generic parameter to itself.
207 pub fn identity_for_item(tcx
: TyCtxt
<'tcx
>, def_id
: DefId
) -> SubstsRef
<'tcx
> {
208 Self::for_item(tcx
, def_id
, |param
, _
| tcx
.mk_param_from_def(param
))
211 /// Creates a `InternalSubsts` for generic parameter definitions,
212 /// by calling closures to obtain each kind.
213 /// The closures get to observe the `InternalSubsts` 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
<'tcx
>, def_id
: DefId
, mut mk_kind
: F
) -> SubstsRef
<'tcx
>
218 F
: FnMut(&ty
::GenericParamDef
, &[GenericArg
<'tcx
>]) -> GenericArg
<'tcx
>,
220 let defs
= tcx
.generics_of(def_id
);
221 let count
= defs
.count();
222 let mut substs
= SmallVec
::with_capacity(count
);
223 Self::fill_item(&mut substs
, tcx
, defs
, &mut mk_kind
);
224 tcx
.intern_substs(&substs
)
227 pub fn extend_to
<F
>(&self, tcx
: TyCtxt
<'tcx
>, def_id
: DefId
, mut mk_kind
: F
) -> SubstsRef
<'tcx
>
229 F
: FnMut(&ty
::GenericParamDef
, &[GenericArg
<'tcx
>]) -> GenericArg
<'tcx
>,
231 Self::for_item(tcx
, def_id
, |param
, substs
| {
232 self.get(param
.index
as usize).cloned().unwrap_or_else(|| mk_kind(param
, substs
))
237 substs
: &mut SmallVec
<[GenericArg
<'tcx
>; 8]>,
242 F
: FnMut(&ty
::GenericParamDef
, &[GenericArg
<'tcx
>]) -> GenericArg
<'tcx
>,
244 if let Some(def_id
) = defs
.parent
{
245 let parent_defs
= tcx
.generics_of(def_id
);
246 Self::fill_item(substs
, tcx
, parent_defs
, mk_kind
);
248 Self::fill_single(substs
, defs
, mk_kind
)
252 substs
: &mut SmallVec
<[GenericArg
<'tcx
>; 8]>,
256 F
: FnMut(&ty
::GenericParamDef
, &[GenericArg
<'tcx
>]) -> GenericArg
<'tcx
>,
258 substs
.reserve(defs
.params
.len());
259 for param
in &defs
.params
{
260 let kind
= mk_kind(param
, substs
);
261 assert_eq
!(param
.index
as usize, substs
.len());
266 pub fn is_noop(&self) -> bool
{
271 pub fn types(&'a
self) -> impl DoubleEndedIterator
<Item
= Ty
<'tcx
>> + 'a
{
273 .filter_map(|k
| if let GenericArgKind
::Type(ty
) = k
.unpack() { Some(ty) }
else { None }
)
277 pub fn regions(&'a
self) -> impl DoubleEndedIterator
<Item
= ty
::Region
<'tcx
>> + 'a
{
278 self.iter().filter_map(|k
| {
279 if let GenericArgKind
::Lifetime(lt
) = k
.unpack() { Some(lt) }
else { None }
284 pub fn consts(&'a
self) -> impl DoubleEndedIterator
<Item
= &'tcx ty
::Const
<'tcx
>> + 'a
{
285 self.iter().filter_map(|k
| {
286 if let GenericArgKind
::Const(ct
) = k
.unpack() { Some(ct) }
else { None }
291 pub fn non_erasable_generics(
293 ) -> impl DoubleEndedIterator
<Item
= GenericArgKind
<'tcx
>> + 'a
{
294 self.iter().filter_map(|k
| match k
.unpack() {
295 GenericArgKind
::Lifetime(_
) => None
,
296 generic
=> Some(generic
),
301 pub fn type_at(&self, i
: usize) -> Ty
<'tcx
> {
302 if let GenericArgKind
::Type(ty
) = self[i
].unpack() {
305 bug
!("expected type for param #{} in {:?}", i
, self);
310 pub fn region_at(&self, i
: usize) -> ty
::Region
<'tcx
> {
311 if let GenericArgKind
::Lifetime(lt
) = self[i
].unpack() {
314 bug
!("expected region for param #{} in {:?}", i
, self);
319 pub fn const_at(&self, i
: usize) -> &'tcx ty
::Const
<'tcx
> {
320 if let GenericArgKind
::Const(ct
) = self[i
].unpack() {
323 bug
!("expected const for param #{} in {:?}", i
, self);
328 pub fn type_for_def(&self, def
: &ty
::GenericParamDef
) -> GenericArg
<'tcx
> {
329 self.type_at(def
.index
as usize).into()
332 /// Transform from substitutions for a child of `source_ancestor`
333 /// (e.g., a trait or impl) to substitutions for the same child
334 /// in a different item, with `target_substs` as the base for
335 /// the target impl/trait, with the source child-specific
336 /// parameters (e.g., method parameters) on top of that base.
338 /// For example given:
341 /// trait X<S> { fn f<T>(); }
342 /// impl<U> X<U> for U { fn f<V>() {} }
345 /// * If `self` is `[Self, S, T]`: the identity substs of `f` in the trait.
346 /// * If `source_ancestor` is the def_id of the trait.
347 /// * If `target_substs` is `[U]`, the substs for the impl.
348 /// * Then we will return `[U, T]`, the subst for `f` in the impl that
349 /// are needed for it to match the trait.
353 source_ancestor
: DefId
,
354 target_substs
: SubstsRef
<'tcx
>,
355 ) -> SubstsRef
<'tcx
> {
356 let defs
= tcx
.generics_of(source_ancestor
);
357 tcx
.mk_substs(target_substs
.iter().chain(self.iter().skip(defs
.params
.len())))
360 pub fn truncate_to(&self, tcx
: TyCtxt
<'tcx
>, generics
: &ty
::Generics
) -> SubstsRef
<'tcx
> {
361 tcx
.mk_substs(self.iter().take(generics
.count()))
365 impl<'tcx
> TypeFoldable
<'tcx
> for SubstsRef
<'tcx
> {
366 fn super_fold_with
<F
: TypeFolder
<'tcx
>>(self, folder
: &mut F
) -> Self {
367 // This code is hot enough that it's worth specializing for the most
368 // common length lists, to avoid the overhead of `SmallVec` creation.
369 // The match arms are in order of frequency. The 1, 2, and 0 cases are
370 // typically hit in 90--99.99% of cases. When folding doesn't change
371 // the substs, it's faster to reuse the existing substs rather than
372 // calling `intern_substs`.
375 let param0
= self[0].fold_with(folder
);
376 if param0
== self[0] { self }
else { folder.tcx().intern_substs(&[param0]) }
379 let param0
= self[0].fold_with(folder
);
380 let param1
= self[1].fold_with(folder
);
381 if param0
== self[0] && param1
== self[1] {
384 folder
.tcx().intern_substs(&[param0
, param1
])
389 let params
: SmallVec
<[_
; 8]> = self.iter().map(|k
| k
.fold_with(folder
)).collect();
390 if params
[..] == self[..] { self }
else { folder.tcx().intern_substs(¶ms) }
395 fn super_visit_with
<V
: TypeVisitor
<'tcx
>>(&self, visitor
: &mut V
) -> ControlFlow
<V
::BreakTy
> {
396 self.iter().try_for_each(|t
| t
.visit_with(visitor
))
400 ///////////////////////////////////////////////////////////////////////////
401 // Public trait `Subst`
403 // Just call `foo.subst(tcx, substs)` to perform a substitution across
404 // `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
405 // there is more information available (for better errors).
407 pub trait Subst
<'tcx
>: Sized
{
408 fn subst(self, tcx
: TyCtxt
<'tcx
>, substs
: &[GenericArg
<'tcx
>]) -> Self {
409 self.subst_spanned(tcx
, substs
, None
)
415 substs
: &[GenericArg
<'tcx
>],
420 impl<'tcx
, T
: TypeFoldable
<'tcx
>> Subst
<'tcx
> for T
{
424 substs
: &[GenericArg
<'tcx
>],
427 let mut folder
= SubstFolder { tcx, substs, span, binders_passed: 0 }
;
428 self.fold_with(&mut folder
)
432 ///////////////////////////////////////////////////////////////////////////
433 // The actual substitution engine itself is a type folder.
435 struct SubstFolder
<'a
, 'tcx
> {
437 substs
: &'a
[GenericArg
<'tcx
>],
439 /// The location for which the substitution is performed, if available.
442 /// Number of region binders we have passed through while doing the substitution
446 impl<'a
, 'tcx
> TypeFolder
<'tcx
> for SubstFolder
<'a
, 'tcx
> {
447 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'tcx
> {
451 fn fold_binder
<T
: TypeFoldable
<'tcx
>>(&mut self, t
: ty
::Binder
<T
>) -> ty
::Binder
<T
> {
452 self.binders_passed
+= 1;
453 let t
= t
.super_fold_with(self);
454 self.binders_passed
-= 1;
458 fn fold_region(&mut self, r
: ty
::Region
<'tcx
>) -> ty
::Region
<'tcx
> {
459 // Note: This routine only handles regions that are bound on
460 // type declarations and other outer declarations, not those
461 // bound in *fn types*. Region substitution of the bound
462 // regions that appear in a function signature is done using
463 // the specialized routine `ty::replace_late_regions()`.
465 ty
::ReEarlyBound(data
) => {
466 let rk
= self.substs
.get(data
.index
as usize).map(|k
| k
.unpack());
468 Some(GenericArgKind
::Lifetime(lt
)) => self.shift_region_through_binders(lt
),
470 let span
= self.span
.unwrap_or(DUMMY_SP
);
472 "Region parameter out of range \
473 when substituting in region {} (index={})",
474 data
.name
, data
.index
476 span_bug
!(span
, "{}", msg
);
484 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
485 if !t
.needs_subst() {
490 ty
::Param(p
) => self.ty_for_param(p
, t
),
491 _
=> t
.super_fold_with(self),
495 fn fold_const(&mut self, c
: &'tcx ty
::Const
<'tcx
>) -> &'tcx ty
::Const
<'tcx
> {
496 if !c
.needs_subst() {
500 if let ty
::ConstKind
::Param(p
) = c
.val
{
501 self.const_for_param(p
, c
)
503 c
.super_fold_with(self)
508 impl<'a
, 'tcx
> SubstFolder
<'a
, 'tcx
> {
509 fn ty_for_param(&self, p
: ty
::ParamTy
, source_ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
510 // Look up the type in the substitutions. It really should be in there.
511 let opt_ty
= self.substs
.get(p
.index
as usize).map(|k
| k
.unpack());
512 let ty
= match opt_ty
{
513 Some(GenericArgKind
::Type(ty
)) => ty
,
515 let span
= self.span
.unwrap_or(DUMMY_SP
);
518 "expected type for `{:?}` ({:?}/{}) but found {:?} \
519 when substituting, substs={:?}",
528 let span
= self.span
.unwrap_or(DUMMY_SP
);
531 "type parameter `{:?}` ({:?}/{}) out of range \
532 when substituting, substs={:?}",
541 self.shift_vars_through_binders(ty
)
547 source_ct
: &'tcx ty
::Const
<'tcx
>,
548 ) -> &'tcx ty
::Const
<'tcx
> {
549 // Look up the const in the substitutions. It really should be in there.
550 let opt_ct
= self.substs
.get(p
.index
as usize).map(|k
| k
.unpack());
551 let ct
= match opt_ct
{
552 Some(GenericArgKind
::Const(ct
)) => ct
,
554 let span
= self.span
.unwrap_or(DUMMY_SP
);
557 "expected const for `{:?}` ({:?}/{}) but found {:?} \
558 when substituting substs={:?}",
567 let span
= self.span
.unwrap_or(DUMMY_SP
);
570 "const parameter `{:?}` ({:?}/{}) out of range \
571 when substituting substs={:?}",
580 self.shift_vars_through_binders(ct
)
583 /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
584 /// when we are substituting a type with escaping bound vars into a context where we have
585 /// passed through binders. That's quite a mouthful. Let's see an example:
588 /// type Func<A> = fn(A);
589 /// type MetaFunc = for<'a> fn(Func<&'a i32>)
592 /// The type `MetaFunc`, when fully expanded, will be
594 /// for<'a> fn(fn(&'a i32))
597 /// | | DebruijnIndex of 2
600 /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
601 /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
602 /// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
603 /// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a
604 /// De Bruijn index of 1. It's only during the substitution that we can see we must increase the
605 /// depth by 1 to account for the binder that we passed through.
607 /// As a second example, consider this twist:
610 /// type FuncTuple<A> = (A,fn(A));
611 /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>)
614 /// Here the final type will be:
616 /// for<'a> fn((&'a i32, fn(&'a i32)))
619 /// DebruijnIndex of 1 |
620 /// DebruijnIndex of 2
622 /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the
623 /// first case we do not increase the De Bruijn index and in the second case we do. The reason
624 /// is that only in the second case have we passed through a fn binder.
625 fn shift_vars_through_binders
<T
: TypeFoldable
<'tcx
>>(&self, val
: T
) -> T
{
627 "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
630 val
.has_escaping_bound_vars()
633 if self.binders_passed
== 0 || !val
.has_escaping_bound_vars() {
637 let result
= ty
::fold
::shift_vars(self.tcx(), val
, self.binders_passed
);
638 debug
!("shift_vars: shifted result = {:?}", result
);
643 fn shift_region_through_binders(&self, region
: ty
::Region
<'tcx
>) -> ty
::Region
<'tcx
> {
644 if self.binders_passed
== 0 || !region
.has_escaping_bound_vars() {
647 ty
::fold
::shift_region(self.tcx
, region
, self.binders_passed
)
651 /// Stores the user-given substs to reach some fully qualified path
652 /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
653 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
654 #[derive(HashStable, TypeFoldable, Lift)]
655 pub struct UserSubsts
<'tcx
> {
656 /// The substitutions for the item as given by the user.
657 pub substs
: SubstsRef
<'tcx
>,
659 /// The self type, in the case of a `<T>::Item` path (when applied
660 /// to an inherent impl). See `UserSelfTy` below.
661 pub user_self_ty
: Option
<UserSelfTy
<'tcx
>>,
664 /// Specifies the user-given self type. In the case of a path that
665 /// refers to a member in an inherent impl, this self type is
666 /// sometimes needed to constrain the type parameters on the impl. For
667 /// example, in this code:
670 /// struct Foo<T> { }
671 /// impl<A> Foo<A> { fn method() { } }
674 /// when you then have a path like `<Foo<&'static u32>>::method`,
675 /// this struct would carry the `DefId` of the impl along with the
676 /// self type `Foo<u32>`. Then we can instantiate the parameters of
677 /// the impl (with the substs from `UserSubsts`) and apply those to
678 /// the self type, giving `Foo<?A>`. Finally, we unify that with
679 /// the self type here, which contains `?A` to be `&'static u32`
680 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
681 #[derive(HashStable, TypeFoldable, Lift)]
682 pub struct UserSelfTy
<'tcx
> {
683 pub impl_def_id
: DefId
,
684 pub self_ty
: Ty
<'tcx
>,