about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-08-08 15:59:31 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-08-24 13:27:38 -0400
commit1884fe35b6b30e02a65bf13a542f0798f220724f (patch)
tree7044a1e4c432eb00ddb9bff8a241328281724155
parent61b00727076ce251b54bdefa18779a13819d2209 (diff)
downloadrust-1884fe35b6b30e02a65bf13a542f0798f220724f.tar.gz
rust-1884fe35b6b30e02a65bf13a542f0798f220724f.zip
add a `user_substs` map into the typeck tables
-rw-r--r--src/librustc/ty/context.rs29
-rw-r--r--src/librustc/ty/subst.rs3
2 files changed, 31 insertions, 1 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 0545a88f36b..388c2455eb3 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -33,7 +33,7 @@ use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use middle::stability;
 use mir::{self, Mir, interpret};
 use mir::interpret::Allocation;
-use ty::subst::{Kind, Substs, Subst};
+use ty::subst::{CanonicalSubsts, Kind, Substs, Subst};
 use ty::ReprOptions;
 use traits;
 use traits::{Clause, Clauses, Goal, Goals};
@@ -371,6 +371,18 @@ pub struct TypeckTables<'tcx> {
     /// other items.
     node_substs: ItemLocalMap<&'tcx Substs<'tcx>>,
 
+    /// Stores the substitutions that the user explicit gave (if any)
+    /// attached to `id`. These will not include any inferred
+    /// values. The canonical form is used to capture things like `_`
+    /// or other unspecified values.
+    ///
+    /// Example:
+    ///
+    /// If the user wrote `foo.collect::<Vec<_>>()`, then the
+    /// canonical substitutions would include only `for<X> { Vec<X>
+    /// }`.
+    user_substs: ItemLocalMap<CanonicalSubsts<'tcx>>,
+
     adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
 
     /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
@@ -444,6 +456,7 @@ impl<'tcx> TypeckTables<'tcx> {
             user_provided_tys: ItemLocalMap(),
             node_types: ItemLocalMap(),
             node_substs: ItemLocalMap(),
+            user_substs: ItemLocalMap(),
             adjustments: ItemLocalMap(),
             pat_binding_modes: ItemLocalMap(),
             pat_adjustments: ItemLocalMap(),
@@ -561,6 +574,18 @@ impl<'tcx> TypeckTables<'tcx> {
         self.node_substs.get(&id.local_id).cloned()
     }
 
+    pub fn user_substs_mut(&mut self) -> LocalTableInContextMut<CanonicalSubsts<'tcx>> {
+        LocalTableInContextMut {
+            local_id_root: self.local_id_root,
+            data: &mut self.user_substs
+        }
+    }
+
+    pub fn user_substs(&self, id: hir::HirId) -> Option<CanonicalSubsts<'tcx>> {
+        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
+        self.user_substs.get(&id.local_id).cloned()
+    }
+
     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
     // doesn't provide type parameter substitutions.
     pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
@@ -740,6 +765,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
             ref user_provided_tys,
             ref node_types,
             ref node_substs,
+            ref user_substs,
             ref adjustments,
             ref pat_binding_modes,
             ref pat_adjustments,
@@ -762,6 +788,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
             user_provided_tys.hash_stable(hcx, hasher);
             node_types.hash_stable(hcx, hasher);
             node_substs.hash_stable(hcx, hasher);
+            user_substs.hash_stable(hcx, hasher);
             adjustments.hash_stable(hcx, hasher);
             pat_binding_modes.hash_stable(hcx, hasher);
             pat_adjustments.hash_stable(hcx, hasher);
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 0e85c68b8b1..26e8b72946b 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -11,6 +11,7 @@
 // Type substitutions.
 
 use hir::def_id::DefId;
+use infer::canonical::Canonical;
 use ty::{self, Lift, List, Ty, TyCtxt};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 
@@ -179,6 +180,8 @@ impl<'tcx> Decodable for Kind<'tcx> {
 /// A substitution mapping generic parameters to new values.
 pub type Substs<'tcx> = List<Kind<'tcx>>;
 
+pub type CanonicalSubsts<'gcx> = Canonical<'gcx, &'gcx Substs<'gcx>>;
+
 impl<'a, 'gcx, 'tcx> Substs<'tcx> {
     /// Creates a Substs that maps each generic parameter to itself.
     pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)