]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/subst.rs
696c4d0043c14993dd374c9c10fc943d339174cc
[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, CanonicalVar, 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             match self.get(param.index as usize) {
209                 Some(&kind) => kind,
210                 None => mk_kind(param, substs),
211             }
212         })
213     }
214
215     fn fill_item<F>(substs: &mut SmallVec<[Kind<'tcx>; 8]>,
216                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
217                     defs: &ty::Generics,
218                     mk_kind: &mut F)
219     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
220     {
221         if let Some(def_id) = defs.parent {
222             let parent_defs = tcx.generics_of(def_id);
223             Substs::fill_item(substs, tcx, parent_defs, mk_kind);
224         }
225         Substs::fill_single(substs, defs, mk_kind)
226     }
227
228     fn fill_single<F>(substs: &mut SmallVec<[Kind<'tcx>; 8]>,
229                       defs: &ty::Generics,
230                       mk_kind: &mut F)
231     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
232     {
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 pub type CanonicalSubsts<'gcx> = Canonical<'gcx, &'gcx Substs<'gcx>>;
327
328 impl<'gcx> CanonicalSubsts<'gcx> {
329     /// True if this represents a substitution like
330     ///
331     /// ```text
332     /// [?0, ?1, ?2]
333     /// ```
334     ///
335     /// i.e., each thing is mapped to a canonical variable with the same index.
336     pub fn is_identity(&self) -> bool {
337         self.value.iter().zip(CanonicalVar::new(0)..).all(|(kind, cvar)| {
338             match kind.unpack() {
339                 UnpackedKind::Type(ty) => match ty.sty {
340                     ty::Infer(ty::CanonicalTy(cvar1)) => cvar == cvar1,
341                     _ => false,
342                 },
343
344                 UnpackedKind::Lifetime(r) => match r {
345                     ty::ReCanonical(cvar1) => cvar == *cvar1,
346                     _ => false,
347                 },
348             }
349         })
350     }
351 }
352
353 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
354
355 ///////////////////////////////////////////////////////////////////////////
356 // Public trait `Subst`
357 //
358 // Just call `foo.subst(tcx, substs)` to perform a substitution across
359 // `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
360 // there is more information available (for better errors).
361
362 pub trait Subst<'tcx> : Sized {
363     fn subst<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
364                       substs: &[Kind<'tcx>]) -> Self {
365         self.subst_spanned(tcx, substs, None)
366     }
367
368     fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
369                                substs: &[Kind<'tcx>],
370                                span: Option<Span>)
371                                -> Self;
372 }
373
374 impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
375     fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
376                                substs: &[Kind<'tcx>],
377                                span: Option<Span>)
378                                -> T
379     {
380         let mut folder = SubstFolder { tcx,
381                                        substs,
382                                        span,
383                                        root_ty: None,
384                                        ty_stack_depth: 0,
385                                        region_binders_passed: 0 };
386         (*self).fold_with(&mut folder)
387     }
388 }
389
390 ///////////////////////////////////////////////////////////////////////////
391 // The actual substitution engine itself is a type folder.
392
393 struct SubstFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
394     tcx: TyCtxt<'a, 'gcx, 'tcx>,
395     substs: &'a [Kind<'tcx>],
396
397     // The location for which the substitution is performed, if available.
398     span: Option<Span>,
399
400     // The root type that is being substituted, if available.
401     root_ty: Option<Ty<'tcx>>,
402
403     // Depth of type stack
404     ty_stack_depth: usize,
405
406     // Number of region binders we have passed through while doing the substitution
407     region_binders_passed: u32,
408 }
409
410 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
411     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
412
413     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
414         self.region_binders_passed += 1;
415         let t = t.super_fold_with(self);
416         self.region_binders_passed -= 1;
417         t
418     }
419
420     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
421         // Note: This routine only handles regions that are bound on
422         // type declarations and other outer declarations, not those
423         // bound in *fn types*. Region substitution of the bound
424         // regions that appear in a function signature is done using
425         // the specialized routine `ty::replace_late_regions()`.
426         match *r {
427             ty::ReEarlyBound(data) => {
428                 let r = self.substs.get(data.index as usize).map(|k| k.unpack());
429                 match r {
430                     Some(UnpackedKind::Lifetime(lt)) => {
431                         self.shift_region_through_binders(lt)
432                     }
433                     _ => {
434                         let span = self.span.unwrap_or(DUMMY_SP);
435                         span_bug!(
436                             span,
437                             "Region parameter out of range \
438                              when substituting in region {} (root type={:?}) \
439                              (index={})",
440                             data.name,
441                             self.root_ty,
442                             data.index);
443                     }
444                 }
445             }
446             _ => r
447         }
448     }
449
450     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
451         if !t.needs_subst() {
452             return t;
453         }
454
455         // track the root type we were asked to substitute
456         let depth = self.ty_stack_depth;
457         if depth == 0 {
458             self.root_ty = Some(t);
459         }
460         self.ty_stack_depth += 1;
461
462         let t1 = match t.sty {
463             ty::Param(p) => {
464                 self.ty_for_param(p, t)
465             }
466             _ => {
467                 t.super_fold_with(self)
468             }
469         };
470
471         assert_eq!(depth + 1, self.ty_stack_depth);
472         self.ty_stack_depth -= 1;
473         if depth == 0 {
474             self.root_ty = None;
475         }
476
477         return t1;
478     }
479 }
480
481 impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
482     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
483         // Look up the type in the substitutions. It really should be in there.
484         let opt_ty = self.substs.get(p.idx as usize).map(|k| k.unpack());
485         let ty = match opt_ty {
486             Some(UnpackedKind::Type(ty)) => ty,
487             _ => {
488                 let span = self.span.unwrap_or(DUMMY_SP);
489                 span_bug!(
490                     span,
491                     "Type parameter `{:?}` ({:?}/{}) out of range \
492                          when substituting (root type={:?}) substs={:?}",
493                     p,
494                     source_ty,
495                     p.idx,
496                     self.root_ty,
497                     self.substs);
498             }
499         };
500
501         self.shift_regions_through_binders(ty)
502     }
503
504     /// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
505     /// when we are substituting a type with escaping regions into a context where we have passed
506     /// through region binders. That's quite a mouthful. Let's see an example:
507     ///
508     /// ```
509     /// type Func<A> = fn(A);
510     /// type MetaFunc = for<'a> fn(Func<&'a int>)
511     /// ```
512     ///
513     /// The type `MetaFunc`, when fully expanded, will be
514     ///
515     ///     for<'a> fn(fn(&'a int))
516     ///             ^~ ^~ ^~~
517     ///             |  |  |
518     ///             |  |  DebruijnIndex of 2
519     ///             Binders
520     ///
521     /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
522     /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
523     /// over the inner binder (remember that we count Debruijn indices from 1). However, in the
524     /// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a
525     /// debruijn index of 1. It's only during the substitution that we can see we must increase the
526     /// depth by 1 to account for the binder that we passed through.
527     ///
528     /// As a second example, consider this twist:
529     ///
530     /// ```
531     /// type FuncTuple<A> = (A,fn(A));
532     /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>)
533     /// ```
534     ///
535     /// Here the final type will be:
536     ///
537     ///     for<'a> fn((&'a int, fn(&'a int)))
538     ///                 ^~~         ^~~
539     ///                 |           |
540     ///          DebruijnIndex of 1 |
541     ///                      DebruijnIndex of 2
542     ///
543     /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
544     /// first case we do not increase the Debruijn index and in the second case we do. The reason
545     /// is that only in the second case have we passed through a fn binder.
546     fn shift_regions_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
547         debug!("shift_regions(ty={:?}, region_binders_passed={:?}, has_escaping_regions={:?})",
548                ty, self.region_binders_passed, ty.has_escaping_regions());
549
550         if self.region_binders_passed == 0 || !ty.has_escaping_regions() {
551             return ty;
552         }
553
554         let result = ty::fold::shift_regions(self.tcx(), self.region_binders_passed, &ty);
555         debug!("shift_regions: shifted result = {:?}", result);
556
557         result
558     }
559
560     fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
561         if self.region_binders_passed == 0 || !region.has_escaping_regions() {
562             return region;
563         }
564         self.tcx().mk_region(ty::fold::shift_region(*region, self.region_binders_passed))
565     }
566 }