diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-07-27 23:12:08 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-07-27 23:14:41 +0300 |
| commit | e268ddf52d7b52b0633572dacdf628c17978f1df (patch) | |
| tree | dc6ac4ac383a572e1337dc0c9e4e2e76492bd037 | |
| parent | 0565653eecd7d667dbb28bb5d3008e783950892a (diff) | |
| download | rust-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.rs | 16 | ||||
| -rw-r--r-- | src/librustc/mir/mod.rs | 20 | ||||
| -rw-r--r-- | src/librustc_mir/dataflow/move_paths/abs_domain.rs | 11 |
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} => |
