提交 e268ddf5 编写于 作者: A Ariel Ben-Yehuda

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.
上级 0565653e
...@@ -258,10 +258,11 @@ fn hash_stable<W: StableHasherResult>(&self, ...@@ -258,10 +258,11 @@ fn hash_stable<W: StableHasherResult>(&self,
} }
} }
impl<'a, 'gcx, 'tcx, B, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for mir::Projection<'tcx, B, V> for mir::Projection<'tcx, B, V, T>
where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, 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, fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
...@@ -276,9 +277,10 @@ fn hash_stable<W: StableHasherResult>(&self, ...@@ -276,9 +277,10 @@ fn hash_stable<W: StableHasherResult>(&self,
} }
} }
impl<'a, 'gcx, 'tcx, V> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for mir::ProjectionElem<'tcx, V> for mir::ProjectionElem<'tcx, V, T>
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
{ {
fn hash_stable<W: StableHasherResult>(&self, fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
...@@ -286,7 +288,7 @@ fn hash_stable<W: StableHasherResult>(&self, ...@@ -286,7 +288,7 @@ fn hash_stable<W: StableHasherResult>(&self,
mem::discriminant(self).hash_stable(hcx, hasher); mem::discriminant(self).hash_stable(hcx, hasher);
match *self { match *self {
mir::ProjectionElem::Deref => {} mir::ProjectionElem::Deref => {}
mir::ProjectionElem::Field(field, ty) => { mir::ProjectionElem::Field(field, ref ty) => {
field.hash_stable(hcx, hasher); field.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher); ty.hash_stable(hcx, hasher);
} }
......
...@@ -887,15 +887,15 @@ pub struct Static<'tcx> { ...@@ -887,15 +887,15 @@ pub struct Static<'tcx> {
/// shared between `Constant` and `Lvalue`. See the aliases /// shared between `Constant` and `Lvalue`. See the aliases
/// `LvalueProjection` etc below. /// `LvalueProjection` etc below.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] #[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 base: B,
pub elem: ProjectionElem<'tcx, V>, pub elem: ProjectionElem<'tcx, V, T>,
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum ProjectionElem<'tcx, V> { pub enum ProjectionElem<'tcx, V, T> {
Deref, Deref,
Field(Field, Ty<'tcx>), Field(Field, T),
Index(V), Index(V),
/// These indices are generated by slice patterns. Easiest to explain /// These indices are generated by slice patterns. Easiest to explain
...@@ -932,11 +932,11 @@ pub enum ProjectionElem<'tcx, V> { ...@@ -932,11 +932,11 @@ pub enum ProjectionElem<'tcx, V> {
/// Alias for projections as they appear in lvalues, where the base is an lvalue /// Alias for projections as they appear in lvalues, where the base is an lvalue
/// and the index is an operand. /// 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 /// Alias for projections as they appear in lvalues, where the base is an lvalue
/// and the index is an operand. /// 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"); newtype_index!(Field, "field");
...@@ -1720,8 +1720,8 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { ...@@ -1720,8 +1720,8 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
} }
} }
impl<'tcx, B, V> TypeFoldable<'tcx> for Projection<'tcx, B, V> impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
where B: TypeFoldable<'tcx>, V: TypeFoldable<'tcx> 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 { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use mir::ProjectionElem::*; use mir::ProjectionElem::*;
...@@ -1729,7 +1729,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) ...@@ -1729,7 +1729,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
let base = self.base.fold_with(folder); let base = self.base.fold_with(folder);
let elem = match self.elem { let elem = match self.elem {
Deref => Deref, 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)), Index(ref v) => Index(v.fold_with(folder)),
ref elem => elem.clone() ref elem => elem.clone()
}; };
...@@ -1745,7 +1745,7 @@ fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool { ...@@ -1745,7 +1745,7 @@ fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
self.base.visit_with(visitor) || self.base.visit_with(visitor) ||
match self.elem { match self.elem {
Field(_, ty) => ty.visit_with(visitor), Field(_, ref ty) => ty.visit_with(visitor),
Index(ref v) => v.visit_with(visitor), Index(ref v) => v.visit_with(visitor),
_ => false _ => false
} }
......
...@@ -23,11 +23,14 @@ ...@@ -23,11 +23,14 @@
use rustc::mir::LvalueElem; use rustc::mir::LvalueElem;
use rustc::mir::{Operand, ProjectionElem}; use rustc::mir::{Operand, ProjectionElem};
use rustc::ty::Ty;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AbstractOperand; pub struct AbstractOperand;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AbstractType;
pub type AbstractElem<'tcx> = pub type AbstractElem<'tcx> =
ProjectionElem<'tcx, AbstractOperand>; ProjectionElem<'tcx, AbstractOperand, AbstractType>;
pub trait Lift { pub trait Lift {
type Abstract; type Abstract;
...@@ -37,6 +40,10 @@ impl<'tcx> Lift for Operand<'tcx> { ...@@ -37,6 +40,10 @@ impl<'tcx> Lift for Operand<'tcx> {
type Abstract = AbstractOperand; type Abstract = AbstractOperand;
fn lift(&self) -> Self::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> { impl<'tcx> Lift for LvalueElem<'tcx> {
type Abstract = AbstractElem<'tcx>; type Abstract = AbstractElem<'tcx>;
fn lift(&self) -> Self::Abstract { fn lift(&self) -> Self::Abstract {
...@@ -44,7 +51,7 @@ fn lift(&self) -> Self::Abstract { ...@@ -44,7 +51,7 @@ fn lift(&self) -> Self::Abstract {
ProjectionElem::Deref => ProjectionElem::Deref =>
ProjectionElem::Deref, ProjectionElem::Deref,
ProjectionElem::Field(ref f, ty) => ProjectionElem::Field(ref f, ty) =>
ProjectionElem::Field(f.clone(), ty.clone()), ProjectionElem::Field(f.clone(), ty.lift()),
ProjectionElem::Index(ref i) => ProjectionElem::Index(ref i) =>
ProjectionElem::Index(i.lift()), ProjectionElem::Index(i.lift()),
ProjectionElem::Subslice {from, to} => ProjectionElem::Subslice {from, to} =>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册