}
}
-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>,
}
}
-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>,
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);
}
/// 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
/// 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");
}
}
-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::*;
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()
};
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
}
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;
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 {
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} =>