]> git.proxmox.com Git - rustc.git/blob - src/librustc_middle/ty/subst.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_middle / ty / subst.rs
1 // Type substitutions.
2
3 use crate::infer::canonical::Canonical;
4 use crate::ty::codec::{TyDecoder, TyEncoder};
5 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
6 use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
7 use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
8
9 use rustc_hir::def_id::DefId;
10 use rustc_macros::HashStable;
11 use rustc_serialize::{self, Decodable, Encodable};
12 use rustc_span::{Span, DUMMY_SP};
13 use smallvec::SmallVec;
14
15 use core::intrinsics;
16 use std::cmp::Ordering;
17 use std::fmt;
18 use std::marker::PhantomData;
19 use std::mem;
20 use std::num::NonZeroUsize;
21
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> {
29 ptr: NonZeroUsize,
30 marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>,
31 }
32
33 const TAG_MASK: usize = 0b11;
34 const TYPE_TAG: usize = 0b00;
35 const REGION_TAG: usize = 0b01;
36 const CONST_TAG: usize = 0b10;
37
38 #[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
39 pub enum GenericArgKind<'tcx> {
40 Lifetime(ty::Region<'tcx>),
41 Type(Ty<'tcx>),
42 Const(&'tcx ty::Const<'tcx>),
43 }
44
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)
52 }
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)
57 }
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)
62 }
63 };
64
65 GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
66 }
67 }
68
69 impl fmt::Debug for GenericArg<'tcx> {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 match self.unpack() {
72 GenericArgKind::Lifetime(lt) => lt.fmt(f),
73 GenericArgKind::Type(ty) => ty.fmt(f),
74 GenericArgKind::Const(ct) => ct.fmt(f),
75 }
76 }
77 }
78
79 impl<'tcx> Ord for GenericArg<'tcx> {
80 fn cmp(&self, other: &GenericArg<'_>) -> Ordering {
81 self.unpack().cmp(&other.unpack())
82 }
83 }
84
85 impl<'tcx> PartialOrd for GenericArg<'tcx> {
86 fn partial_cmp(&self, other: &GenericArg<'_>) -> Option<Ordering> {
87 Some(self.cmp(&other))
88 }
89 }
90
91 impl<'tcx> From<ty::Region<'tcx>> for GenericArg<'tcx> {
92 fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> {
93 GenericArgKind::Lifetime(r).pack()
94 }
95 }
96
97 impl<'tcx> From<Ty<'tcx>> for GenericArg<'tcx> {
98 fn from(ty: Ty<'tcx>) -> GenericArg<'tcx> {
99 GenericArgKind::Type(ty).pack()
100 }
101 }
102
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()
106 }
107 }
108
109 impl<'tcx> GenericArg<'tcx> {
110 #[inline]
111 pub fn unpack(self) -> GenericArgKind<'tcx> {
112 let ptr = self.ptr.get();
113 unsafe {
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(),
119 }
120 }
121 }
122
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"),
130 }
131 }
132
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"),
138 }
139 }
140 }
141
142 impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
143 type Lifted = GenericArg<'tcx>;
144
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()),
150 }
151 }
152 }
153
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(),
160 }
161 }
162
163 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
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),
168 }
169 }
170 }
171
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)
175 }
176 }
177
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())
181 }
182 }
183
184 /// A substitution mapping generic parameters to new values.
185 pub type InternalSubsts<'tcx> = List<GenericArg<'tcx>>;
186
187 pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
188
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 }
196 }
197
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 }
204 }
205
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))
209 }
210
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>
217 where
218 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
219 {
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)
225 }
226
227 pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
228 where
229 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
230 {
231 Self::for_item(tcx, def_id, |param, substs| {
232 self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, substs))
233 })
234 }
235
236 fn fill_item<F>(
237 substs: &mut SmallVec<[GenericArg<'tcx>; 8]>,
238 tcx: TyCtxt<'tcx>,
239 defs: &ty::Generics,
240 mk_kind: &mut F,
241 ) where
242 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
243 {
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);
247 }
248 Self::fill_single(substs, defs, mk_kind)
249 }
250
251 fn fill_single<F>(
252 substs: &mut SmallVec<[GenericArg<'tcx>; 8]>,
253 defs: &ty::Generics,
254 mk_kind: &mut F,
255 ) where
256 F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
257 {
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());
262 substs.push(kind);
263 }
264 }
265
266 pub fn is_noop(&self) -> bool {
267 self.is_empty()
268 }
269
270 #[inline]
271 pub fn types(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
272 self.iter()
273 .filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None })
274 }
275
276 #[inline]
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 }
280 })
281 }
282
283 #[inline]
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 }
287 })
288 }
289
290 #[inline]
291 pub fn non_erasable_generics(
292 &'a self,
293 ) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> + 'a {
294 self.iter().filter_map(|k| match k.unpack() {
295 GenericArgKind::Lifetime(_) => None,
296 generic => Some(generic),
297 })
298 }
299
300 #[inline]
301 pub fn type_at(&self, i: usize) -> Ty<'tcx> {
302 if let GenericArgKind::Type(ty) = self[i].unpack() {
303 ty
304 } else {
305 bug!("expected type for param #{} in {:?}", i, self);
306 }
307 }
308
309 #[inline]
310 pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
311 if let GenericArgKind::Lifetime(lt) = self[i].unpack() {
312 lt
313 } else {
314 bug!("expected region for param #{} in {:?}", i, self);
315 }
316 }
317
318 #[inline]
319 pub fn const_at(&self, i: usize) -> &'tcx ty::Const<'tcx> {
320 if let GenericArgKind::Const(ct) = self[i].unpack() {
321 ct
322 } else {
323 bug!("expected const for param #{} in {:?}", i, self);
324 }
325 }
326
327 #[inline]
328 pub fn type_for_def(&self, def: &ty::GenericParamDef) -> GenericArg<'tcx> {
329 self.type_at(def.index as usize).into()
330 }
331
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.
337 ///
338 /// For example given:
339 ///
340 /// ```no_run
341 /// trait X<S> { fn f<T>(); }
342 /// impl<U> X<U> for U { fn f<V>() {} }
343 /// ```
344 ///
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.
350 pub fn rebase_onto(
351 &self,
352 tcx: TyCtxt<'tcx>,
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())))
358 }
359
360 pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
361 tcx.mk_substs(self.iter().take(generics.count()))
362 }
363 }
364
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`.
373 match self.len() {
374 1 => {
375 let param0 = self[0].fold_with(folder);
376 if param0 == self[0] { self } else { folder.tcx().intern_substs(&[param0]) }
377 }
378 2 => {
379 let param0 = self[0].fold_with(folder);
380 let param1 = self[1].fold_with(folder);
381 if param0 == self[0] && param1 == self[1] {
382 self
383 } else {
384 folder.tcx().intern_substs(&[param0, param1])
385 }
386 }
387 0 => self,
388 _ => {
389 let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
390 if params[..] == self[..] { self } else { folder.tcx().intern_substs(&params) }
391 }
392 }
393 }
394
395 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
396 self.iter().any(|t| t.visit_with(visitor))
397 }
398 }
399
400 ///////////////////////////////////////////////////////////////////////////
401 // Public trait `Subst`
402 //
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).
406
407 pub trait Subst<'tcx>: Sized {
408 fn subst(&self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self {
409 self.subst_spanned(tcx, substs, None)
410 }
411
412 fn subst_spanned(
413 &self,
414 tcx: TyCtxt<'tcx>,
415 substs: &[GenericArg<'tcx>],
416 span: Option<Span>,
417 ) -> Self;
418 }
419
420 impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
421 fn subst_spanned(
422 &self,
423 tcx: TyCtxt<'tcx>,
424 substs: &[GenericArg<'tcx>],
425 span: Option<Span>,
426 ) -> T {
427 let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
428 (*self).fold_with(&mut folder)
429 }
430 }
431
432 ///////////////////////////////////////////////////////////////////////////
433 // The actual substitution engine itself is a type folder.
434
435 struct SubstFolder<'a, 'tcx> {
436 tcx: TyCtxt<'tcx>,
437 substs: &'a [GenericArg<'tcx>],
438
439 /// The location for which the substitution is performed, if available.
440 span: Option<Span>,
441
442 /// Number of region binders we have passed through while doing the substitution
443 binders_passed: u32,
444 }
445
446 impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
447 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
448 self.tcx
449 }
450
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;
455 t
456 }
457
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()`.
464 match *r {
465 ty::ReEarlyBound(data) => {
466 let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
467 match rk {
468 Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
469 _ => {
470 let span = self.span.unwrap_or(DUMMY_SP);
471 let msg = format!(
472 "Region parameter out of range \
473 when substituting in region {} (index={})",
474 data.name, data.index
475 );
476 span_bug!(span, "{}", msg);
477 }
478 }
479 }
480 _ => r,
481 }
482 }
483
484 fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
485 if !t.needs_subst() {
486 return t;
487 }
488
489 match t.kind {
490 ty::Param(p) => self.ty_for_param(p, t),
491 _ => t.super_fold_with(self),
492 }
493 }
494
495 fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
496 if !c.needs_subst() {
497 return c;
498 }
499
500 if let ty::ConstKind::Param(p) = c.val {
501 self.const_for_param(p, c)
502 } else {
503 c.super_fold_with(self)
504 }
505 }
506 }
507
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,
514 Some(kind) => {
515 let span = self.span.unwrap_or(DUMMY_SP);
516 span_bug!(
517 span,
518 "expected type for `{:?}` ({:?}/{}) but found {:?} \
519 when substituting, substs={:?}",
520 p,
521 source_ty,
522 p.index,
523 kind,
524 self.substs,
525 );
526 }
527 None => {
528 let span = self.span.unwrap_or(DUMMY_SP);
529 span_bug!(
530 span,
531 "type parameter `{:?}` ({:?}/{}) out of range \
532 when substituting, substs={:?}",
533 p,
534 source_ty,
535 p.index,
536 self.substs,
537 );
538 }
539 };
540
541 self.shift_vars_through_binders(ty)
542 }
543
544 fn const_for_param(
545 &self,
546 p: ParamConst,
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,
553 Some(kind) => {
554 let span = self.span.unwrap_or(DUMMY_SP);
555 span_bug!(
556 span,
557 "expected const for `{:?}` ({:?}/{}) but found {:?} \
558 when substituting substs={:?}",
559 p,
560 source_ct,
561 p.index,
562 kind,
563 self.substs,
564 );
565 }
566 None => {
567 let span = self.span.unwrap_or(DUMMY_SP);
568 span_bug!(
569 span,
570 "const parameter `{:?}` ({:?}/{}) out of range \
571 when substituting substs={:?}",
572 p,
573 source_ct,
574 p.index,
575 self.substs,
576 );
577 }
578 };
579
580 self.shift_vars_through_binders(ct)
581 }
582
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:
586 ///
587 /// ```
588 /// type Func<A> = fn(A);
589 /// type MetaFunc = for<'a> fn(Func<&'a i32>)
590 /// ```
591 ///
592 /// The type `MetaFunc`, when fully expanded, will be
593 ///
594 /// for<'a> fn(fn(&'a i32))
595 /// ^~ ^~ ^~~
596 /// | | |
597 /// | | DebruijnIndex of 2
598 /// Binders
599 ///
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.
606 ///
607 /// As a second example, consider this twist:
608 ///
609 /// ```
610 /// type FuncTuple<A> = (A,fn(A));
611 /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>)
612 /// ```
613 ///
614 /// Here the final type will be:
615 ///
616 /// for<'a> fn((&'a i32, fn(&'a i32)))
617 /// ^~~ ^~~
618 /// | |
619 /// DebruijnIndex of 1 |
620 /// DebruijnIndex of 2
621 ///
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 {
626 debug!(
627 "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
628 val,
629 self.binders_passed,
630 val.has_escaping_bound_vars()
631 );
632
633 if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
634 return val;
635 }
636
637 let result = ty::fold::shift_vars(self.tcx(), &val, self.binders_passed);
638 debug!("shift_vars: shifted result = {:?}", result);
639
640 result
641 }
642
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() {
645 return region;
646 }
647 ty::fold::shift_region(self.tcx, region, self.binders_passed)
648 }
649 }
650
651 pub type CanonicalUserSubsts<'tcx> = Canonical<'tcx, UserSubsts<'tcx>>;
652
653 /// Stores the user-given substs to reach some fully qualified path
654 /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
655 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
656 #[derive(HashStable, TypeFoldable, Lift)]
657 pub struct UserSubsts<'tcx> {
658 /// The substitutions for the item as given by the user.
659 pub substs: SubstsRef<'tcx>,
660
661 /// The self type, in the case of a `<T>::Item` path (when applied
662 /// to an inherent impl). See `UserSelfTy` below.
663 pub user_self_ty: Option<UserSelfTy<'tcx>>,
664 }
665
666 /// Specifies the user-given self type. In the case of a path that
667 /// refers to a member in an inherent impl, this self type is
668 /// sometimes needed to constrain the type parameters on the impl. For
669 /// example, in this code:
670 ///
671 /// ```
672 /// struct Foo<T> { }
673 /// impl<A> Foo<A> { fn method() { } }
674 /// ```
675 ///
676 /// when you then have a path like `<Foo<&'static u32>>::method`,
677 /// this struct would carry the `DefId` of the impl along with the
678 /// self type `Foo<u32>`. Then we can instantiate the parameters of
679 /// the impl (with the substs from `UserSubsts`) and apply those to
680 /// the self type, giving `Foo<?A>`. Finally, we unify that with
681 /// the self type here, which contains `?A` to be `&'static u32`
682 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
683 #[derive(HashStable, TypeFoldable, Lift)]
684 pub struct UserSelfTy<'tcx> {
685 pub impl_def_id: DefId,
686 pub self_ty: Ty<'tcx>,
687 }