about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-07-27 23:12:08 +0300
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-07-27 23:14:41 +0300
commite268ddf52d7b52b0633572dacdf628c17978f1df (patch)
treedc6ac4ac383a572e1337dc0c9e4e2e76492bd037
parent0565653eecd7d667dbb28bb5d3008e783950892a (diff)
downloadrust-e268ddf52d7b52b0633572dacdf628c17978f1df.tar.gz
rust-e268ddf52d7b52b0633572dacdf628c17978f1df.zip
erase types in the move-path abstract domain
Leaving types unerased would lead to 2 types with a different "name"
getting different move-paths, which would cause major brokenness (see
e.g. #42903).

This does not fix any *known* issue, but is required if we want to use
abs_domain with non-erased regions (because the same can easily
have different names). cc @RalfJung.
-rw-r--r--src/librustc/ich/impls_mir.rs16
-rw-r--r--src/librustc/mir/mod.rs20
-rw-r--r--src/librustc_mir/dataflow/move_paths/abs_domain.rs11
3 files changed, 28 insertions, 19 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index cb017b7f886..6dadb702b9f 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -258,10 +258,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::L
     }
 }
 
-impl<'a, 'gcx, 'tcx, B, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
-for mir::Projection<'tcx, B, V>
+impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
+for mir::Projection<'tcx, B, V, T>
     where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
-          V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
+          V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
+          T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
 {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
@@ -276,9 +277,10 @@ for mir::Projection<'tcx, B, V>
     }
 }
 
-impl<'a, 'gcx, 'tcx, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
-for mir::ProjectionElem<'tcx, V>
-    where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
+impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
+for mir::ProjectionElem<'tcx, V, T>
+    where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
+          T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
 {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
@@ -286,7 +288,7 @@ for mir::ProjectionElem<'tcx, V>
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
             mir::ProjectionElem::Deref => {}
-            mir::ProjectionElem::Field(field, ty) => {
+            mir::ProjectionElem::Field(field, ref ty) => {
                 field.hash_stable(hcx, hasher);
                 ty.hash_stable(hcx, hasher);
             }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index d78e17ce03c..3dcd64af2ed 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -887,15 +887,15 @@ impl_stable_hash_for!(struct Static<'tcx> {
 /// shared between `Constant` and `Lvalue`. See the aliases
 /// `LvalueProjection` etc below.
 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-pub struct Projection<'tcx, B, V> {
+pub struct Projection<'tcx, B, V, T> {
     pub base: B,
-    pub elem: ProjectionElem<'tcx, V>,
+    pub elem: ProjectionElem<'tcx, V, T>,
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-pub enum ProjectionElem<'tcx, V> {
+pub enum ProjectionElem<'tcx, V, T> {
     Deref,
-    Field(Field, Ty<'tcx>),
+    Field(Field, T),
     Index(V),
 
     /// These indices are generated by slice patterns. Easiest to explain
@@ -932,11 +932,11 @@ pub enum ProjectionElem<'tcx, V> {
 
 /// Alias for projections as they appear in lvalues, where the base is an lvalue
 /// and the index is an operand.
-pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
+pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>, Ty<'tcx>>;
 
 /// Alias for projections as they appear in lvalues, where the base is an lvalue
 /// and the index is an operand.
-pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>>;
+pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>, Ty<'tcx>>;
 
 newtype_index!(Field, "field");
 
@@ -1720,8 +1720,8 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
     }
 }
 
-impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V>
-    where B: TypeFoldable<'tcx>, V: TypeFoldable<'tcx>
+impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
+    where B: TypeFoldable<'tcx>, V: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>
 {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         use mir::ProjectionElem::*;
@@ -1729,7 +1729,7 @@ impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V>
         let base = self.base.fold_with(folder);
         let elem = match self.elem {
             Deref => Deref,
-            Field(f, ty) => Field(f, ty.fold_with(folder)),
+            Field(f, ref ty) => Field(f, ty.fold_with(folder)),
             Index(ref v) => Index(v.fold_with(folder)),
             ref elem => elem.clone()
         };
@@ -1745,7 +1745,7 @@ impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V>
 
         self.base.visit_with(visitor) ||
             match self.elem {
-                Field(_, ty) => ty.visit_with(visitor),
+                Field(_, ref ty) => ty.visit_with(visitor),
                 Index(ref v) => v.visit_with(visitor),
                 _ => false
             }
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index 5e61c2ec7a2..1255209322b 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -23,11 +23,14 @@
 
 use rustc::mir::LvalueElem;
 use rustc::mir::{Operand, ProjectionElem};
+use rustc::ty::Ty;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct AbstractOperand;
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub struct AbstractType;
 pub type AbstractElem<'tcx> =
-    ProjectionElem<'tcx, AbstractOperand>;
+    ProjectionElem<'tcx, AbstractOperand, AbstractType>;
 
 pub trait Lift {
     type Abstract;
@@ -37,6 +40,10 @@ impl<'tcx> Lift for Operand<'tcx> {
     type Abstract = AbstractOperand;
     fn lift(&self) -> Self::Abstract { AbstractOperand }
 }
+impl<'tcx> Lift for Ty<'tcx> {
+    type Abstract = AbstractType;
+    fn lift(&self) -> Self::Abstract { AbstractType }
+}
 impl<'tcx> Lift for LvalueElem<'tcx> {
     type Abstract = AbstractElem<'tcx>;
     fn lift(&self) -> Self::Abstract {
@@ -44,7 +51,7 @@ impl<'tcx> Lift for LvalueElem<'tcx> {
             ProjectionElem::Deref =>
                 ProjectionElem::Deref,
             ProjectionElem::Field(ref f, ty) =>
-                ProjectionElem::Field(f.clone(), ty.clone()),
+                ProjectionElem::Field(f.clone(), ty.lift()),
             ProjectionElem::Index(ref i) =>
                 ProjectionElem::Index(i.lift()),
             ProjectionElem::Subslice {from, to} =>