Skip to content

Commit

Permalink
Replace adt_def with name in mir::ProjectionElem::Downcast
Browse files Browse the repository at this point in the history
  • Loading branch information
tmandry committed Apr 2, 2019
1 parent f694222 commit ac29ca7
Show file tree
Hide file tree
Showing 15 changed files with 124 additions and 98 deletions.
69 changes: 39 additions & 30 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::slice;
use std::vec::IntoIter;
use std::{iter, mem, option, u32};
use syntax::ast::{self, Name};
use syntax::symbol::InternedString;
use syntax::symbol::{InternedString, Symbol};
use syntax_pos::{Span, DUMMY_SP};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::subst::{Subst, SubstsRef};
Expand Down Expand Up @@ -772,7 +772,7 @@ pub struct LocalDecl<'tcx> {
/// e.g., via `let x: T`, then we carry that type here. The MIR
/// borrow checker needs this information since it can affect
/// region inference.
pub user_ty: UserTypeProjections<'tcx>,
pub user_ty: UserTypeProjections,

/// Name of the local, used in debuginfo and pretty-printing.
///
Expand Down Expand Up @@ -1805,7 +1805,7 @@ pub enum StatementKind<'tcx> {
/// - `Contravariant` -- requires that `T_y :> T`
/// - `Invariant` -- requires that `T_y == T`
/// - `Bivariant` -- no effect
AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeProjection<'tcx>>),
AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeProjection>),

/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
Expand Down Expand Up @@ -1939,14 +1939,14 @@ impl_stable_hash_for!(struct Static<'tcx> {
/// `PlaceProjection` etc below.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
Hash, RustcEncodable, RustcDecodable, HashStable)]
pub struct Projection<'tcx, B, V, T> {
pub struct Projection<B, V, T> {
pub base: B,
pub elem: ProjectionElem<'tcx, V, T>,
pub elem: ProjectionElem<V, T>,
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
Hash, RustcEncodable, RustcDecodable, HashStable)]
pub enum ProjectionElem<'tcx, V, T> {
pub enum ProjectionElem<V, T> {
Deref,
Field(Field, T),
Index(V),
Expand Down Expand Up @@ -1980,16 +1980,18 @@ pub enum ProjectionElem<'tcx, V, T> {
/// "Downcast" to a variant of an ADT. Currently, we only introduce
/// this for ADTs with more than one variant. It may be better to
/// just introduce it always, or always for enums.
Downcast(&'tcx AdtDef, VariantIdx),
///
/// The included Symbol is the name of the variant, used for printing MIR.
Downcast(Option<Symbol>, VariantIdx),
}

/// Alias for projections as they appear in places, where the base is a place
/// and the index is a local.
pub type PlaceProjection<'tcx> = Projection<'tcx, Place<'tcx>, Local, Ty<'tcx>>;
pub type PlaceProjection<'tcx> = Projection<Place<'tcx>, Local, Ty<'tcx>>;

/// Alias for projections as they appear in places, where the base is a place
/// and the index is a local.
pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;

// at least on 64 bit systems, `PlaceElem` should not be larger than two pointers
static_assert!(PROJECTION_ELEM_IS_2_PTRS_LARGE:
Expand All @@ -1998,7 +2000,7 @@ static_assert!(PROJECTION_ELEM_IS_2_PTRS_LARGE:

/// Alias for projections as they appear in `UserTypeProjection`, where we
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
pub type ProjectionKind<'tcx> = ProjectionElem<'tcx, (), ()>;
pub type ProjectionKind = ProjectionElem<(), ()>;

newtype_index! {
pub struct Field {
Expand All @@ -2019,7 +2021,9 @@ impl<'tcx> Place<'tcx> {
}

pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Place<'tcx> {
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
self.elem(ProjectionElem::Downcast(
Some(adt_def.variants[variant_index].ident.name),
variant_index))
}

pub fn index(self, index: Local) -> Place<'tcx> {
Expand Down Expand Up @@ -2080,8 +2084,11 @@ impl<'tcx> Debug for Place<'tcx> {
)
},
Projection(ref data) => match data.elem {
ProjectionElem::Downcast(ref adt_def, index) => {
write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident)
ProjectionElem::Downcast(Some(name), _index) => {
write!(fmt, "({:?} as {})", data.base, name)
}
ProjectionElem::Downcast(None, index) => {
write!(fmt, "({:?} as variant#{:?})", data.base, index)
}
ProjectionElem::Deref => write!(fmt, "(*{:?})", data.base),
ProjectionElem::Field(field, ty) => {
Expand Down Expand Up @@ -2542,36 +2549,36 @@ pub struct Constant<'tcx> {
/// inferred region `'1`). The second will lead to the constraint `w:
/// &'static str`.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
pub struct UserTypeProjections<'tcx> {
pub(crate) contents: Vec<(UserTypeProjection<'tcx>, Span)>,
pub struct UserTypeProjections {
pub(crate) contents: Vec<(UserTypeProjection, Span)>,
}

BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjections<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjections {
contents
}
}

impl<'tcx> UserTypeProjections<'tcx> {
impl<'tcx> UserTypeProjections {
pub fn none() -> Self {
UserTypeProjections { contents: vec![] }
}

pub fn from_projections(projs: impl Iterator<Item=(UserTypeProjection<'tcx>, Span)>) -> Self {
pub fn from_projections(projs: impl Iterator<Item=(UserTypeProjection, Span)>) -> Self {
UserTypeProjections { contents: projs.collect() }
}

pub fn projections_and_spans(&self) -> impl Iterator<Item=&(UserTypeProjection<'tcx>, Span)> {
pub fn projections_and_spans(&self) -> impl Iterator<Item=&(UserTypeProjection, Span)> {
self.contents.iter()
}

pub fn projections(&self) -> impl Iterator<Item=&UserTypeProjection<'tcx>> {
pub fn projections(&self) -> impl Iterator<Item=&UserTypeProjection> {
self.contents.iter().map(|&(ref user_type, _span)| user_type)
}

pub fn push_projection(
mut self,
user_ty: &UserTypeProjection<'tcx>,
user_ty: &UserTypeProjection,
span: Span,
) -> Self {
self.contents.push((user_ty.clone(), span));
Expand All @@ -2580,7 +2587,7 @@ impl<'tcx> UserTypeProjections<'tcx> {

fn map_projections(
mut self,
mut f: impl FnMut(UserTypeProjection<'tcx>) -> UserTypeProjection<'tcx>
mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection
) -> Self {
self.contents = self.contents.drain(..).map(|(proj, span)| (f(proj), span)).collect();
self
Expand Down Expand Up @@ -2628,14 +2635,14 @@ impl<'tcx> UserTypeProjections<'tcx> {
/// `field[0]` (aka `.0`), indicating that the type of `s` is
/// determined by finding the type of the `.0` field from `T`.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
pub struct UserTypeProjection<'tcx> {
pub struct UserTypeProjection {
pub base: UserTypeAnnotationIndex,
pub projs: Vec<ProjectionElem<'tcx, (), ()>>,
pub projs: Vec<ProjectionElem<(), ()>>,
}

impl<'tcx> Copy for ProjectionKind<'tcx> { }
impl Copy for ProjectionKind { }

impl<'tcx> UserTypeProjection<'tcx> {
impl UserTypeProjection {
pub(crate) fn index(mut self) -> Self {
self.projs.push(ProjectionElem::Index(()));
self
Expand All @@ -2662,15 +2669,17 @@ impl<'tcx> UserTypeProjection<'tcx> {
variant_index: VariantIdx,
field: Field,
) -> Self {
self.projs.push(ProjectionElem::Downcast(adt_def, variant_index));
self.projs.push(ProjectionElem::Downcast(
Some(adt_def.variants[variant_index].ident.name),
variant_index));
self.projs.push(ProjectionElem::Field(field, ()));
self
}
}

CloneTypeFoldableAndLiftImpls! { ProjectionKind<'tcx>, }
CloneTypeFoldableAndLiftImpls! { ProjectionKind, }

impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use crate::mir::ProjectionElem::*;

Expand Down Expand Up @@ -3428,7 +3437,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
}
}

impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<B, V, T>
where
B: TypeFoldable<'tcx>,
V: TypeFoldable<'tcx>,
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
pub fn projection_ty_core<V, T>(
self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
elem: &ProjectionElem<'tcx, V, T>,
elem: &ProjectionElem<V, T>,
mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>)
-> PlaceTy<'tcx>
where
Expand Down Expand Up @@ -124,12 +124,11 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
}
}
}
ProjectionElem::Downcast(adt_def1, index) =>
ProjectionElem::Downcast(_name, index) =>
match self.to_ty(tcx).sty {
ty::Adt(adt_def, substs) => {
assert!(adt_def.is_enum());
assert!(index.as_usize() < adt_def.variants.len());
assert_eq!(adt_def, adt_def1);
PlaceTy::Downcast { adt_def,
substs,
variant_index: index }
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ macro_rules! make_mir_visitor {
fn visit_ascribe_user_ty(&mut self,
place: & $($mutability)? Place<'tcx>,
variance: & $($mutability)? ty::Variance,
user_ty: & $($mutability)? UserTypeProjection<'tcx>,
user_ty: & $($mutability)? UserTypeProjection,
location: Location) {
self.super_ascribe_user_ty(place, variance, user_ty, location);
}
Expand Down Expand Up @@ -205,7 +205,7 @@ macro_rules! make_mir_visitor {

fn visit_user_type_projection(
&mut self,
ty: & $($mutability)? UserTypeProjection<'tcx>,
ty: & $($mutability)? UserTypeProjection,
) {
self.super_user_type_projection(ty);
}
Expand Down Expand Up @@ -700,7 +700,7 @@ macro_rules! make_mir_visitor {
fn super_ascribe_user_ty(&mut self,
place: & $($mutability)? Place<'tcx>,
_variance: & $($mutability)? ty::Variance,
user_ty: & $($mutability)? UserTypeProjection<'tcx>,
user_ty: & $($mutability)? UserTypeProjection,
location: Location) {
self.visit_place(
place,
Expand Down Expand Up @@ -777,7 +777,7 @@ macro_rules! make_mir_visitor {
min_length: _,
from_end: _ } => {
}
ProjectionElem::Downcast(_adt_def, _variant_index) => {
ProjectionElem::Downcast(_name, _variant_index) => {
}
}
}
Expand Down Expand Up @@ -851,7 +851,7 @@ macro_rules! make_mir_visitor {

fn super_user_type_projection(
&mut self,
_ty: & $($mutability)? UserTypeProjection<'tcx>,
_ty: & $($mutability)? UserTypeProjection,
) {
}

Expand Down
32 changes: 16 additions & 16 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub struct CtxtInterners<'tcx> {
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
goal: InternedSet<'tcx, GoalKind<'tcx>>,
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
const_: InternedSet<'tcx, Const<'tcx>>,
}

Expand Down Expand Up @@ -1802,7 +1802,7 @@ nop_list_lift!{Ty<'a> => Ty<'tcx>}
nop_list_lift!{ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
nop_list_lift!{Predicate<'a> => Predicate<'tcx>}
nop_list_lift!{CanonicalVarInfo => CanonicalVarInfo}
nop_list_lift!{ProjectionKind<'a> => ProjectionKind<'tcx>}
nop_list_lift!{ProjectionKind => ProjectionKind}

// this is the impl for `&'a InternalSubsts<'a>`
nop_list_lift!{Kind<'a> => Kind<'tcx>}
Expand Down Expand Up @@ -2261,9 +2261,9 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, InternalSubsts<'t
}
}

impl<'tcx: 'lcx, 'lcx> Borrow<[ProjectionKind<'lcx>]>
for Interned<'tcx, List<ProjectionKind<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a [ProjectionKind<'lcx>] {
impl<'tcx> Borrow<[ProjectionKind]>
for Interned<'tcx, List<ProjectionKind>> {
fn borrow<'a>(&'a self) -> &'a [ProjectionKind] {
&self.0[..]
}
}
Expand Down Expand Up @@ -2391,22 +2391,22 @@ direct_interners!('tcx,
);

macro_rules! slice_interners {
($($field:ident: $method:ident($ty:ident)),+) => (
($($field:ident: $method:ident($ty:ty)),+) => (
$(intern_method!( 'tcx, $field: $method(
&[$ty<'tcx>],
&[$ty],
|a, v| List::from_arena(a, v),
Deref::deref,
|xs: &[$ty<'_>]| xs.iter().any(keep_local)) -> List<$ty<'tcx>>);)+
)
|xs: &[$ty]| xs.iter().any(keep_local)) -> List<$ty>);)+
);
}

slice_interners!(
existential_predicates: _intern_existential_predicates(ExistentialPredicate),
predicates: _intern_predicates(Predicate),
type_list: _intern_type_list(Ty),
substs: _intern_substs(Kind),
clauses: _intern_clauses(Clause),
goal_list: _intern_goals(Goal),
existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
predicates: _intern_predicates(Predicate<'tcx>),
type_list: _intern_type_list(Ty<'tcx>),
substs: _intern_substs(Kind<'tcx>),
clauses: _intern_clauses(Clause<'tcx>),
goal_list: _intern_goals(Goal<'tcx>),
projs: _intern_projs(ProjectionKind)
);

Expand Down Expand Up @@ -2774,7 +2774,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

pub fn intern_projs(self, ps: &[ProjectionKind<'tcx>]) -> &'tcx List<ProjectionKind<'tcx>> {
pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
if ps.len() == 0 {
List::empty()
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
}
}

impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind<'tcx>> {
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
folder.tcx().intern_projs(&v)
Expand Down
Loading

0 comments on commit ac29ca7

Please sign in to comment.