Skip to content

Commit

Permalink
Remove adt_def from PlaceTy and make it a struct
Browse files Browse the repository at this point in the history
  • Loading branch information
tmandry committed Apr 2, 2019
1 parent ac29ca7 commit 4122d22
Show file tree
Hide file tree
Showing 30 changed files with 157 additions and 196 deletions.
116 changes: 42 additions & 74 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@
*/

use crate::mir::*;
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{self, AdtDef, Ty, TyCtxt};
use crate::ty::subst::Subst;
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::layout::VariantIdx;
use crate::hir;
use crate::ty::util::IntTypeExt;

#[derive(Copy, Clone, Debug)]
pub enum PlaceTy<'tcx> {
/// Normal type.
Ty { ty: Ty<'tcx> },

/// Downcast to a particular variant of an enum.
Downcast { adt_def: &'tcx AdtDef,
substs: SubstsRef<'tcx>,
variant_index: VariantIdx },
pub struct PlaceTy<'tcx> {
pub ty: Ty<'tcx>,
/// Downcast to a particular variant of an enum, if included.
pub variant_index: Option<VariantIdx>,
}

static_assert!(PLACE_TY_IS_3_PTRS_LARGE:
Expand All @@ -27,16 +23,7 @@ static_assert!(PLACE_TY_IS_3_PTRS_LARGE:

impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
PlaceTy::Ty { ty }
}

pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
match *self {
PlaceTy::Ty { ty } =>
ty,
PlaceTy::Downcast { adt_def, substs, variant_index: _ } =>
tcx.mk_adt(adt_def, substs),
}
PlaceTy { ty, variant_index: None }
}

/// `place_ty.field_ty(tcx, f)` computes the type at a given field
Expand All @@ -48,21 +35,20 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
/// Note that the resulting type has not been normalized.
pub fn field_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, f: &Field) -> Ty<'tcx>
{
// Pass `0` here so it can be used as a "default" variant_index in first arm below
let answer = match (self, VariantIdx::new(0)) {
(PlaceTy::Ty {
ty: &ty::TyS { sty: ty::TyKind::Adt(adt_def, substs), .. } }, variant_index) |
(PlaceTy::Downcast { adt_def, substs, variant_index }, _) => {
let variant_def = &adt_def.variants[variant_index];
let answer = match self.ty.sty {
ty::TyKind::Adt(adt_def, substs) => {
let variant_def = match self.variant_index {
None => adt_def.non_enum_variant(),
Some(variant_index) => {
assert!(adt_def.is_enum());
&adt_def.variants[variant_index]
}
};
let field_def = &variant_def.fields[f.index()];
field_def.ty(tcx, substs)
}
(PlaceTy::Ty { ty }, _) => {
match ty.sty {
ty::Tuple(ref tys) => tys[f.index()],
_ => bug!("extracting field of non-tuple non-adt: {:?}", self),
}
}
ty::Tuple(ref tys) => tys[f.index()],
_ => bug!("extracting field of non-tuple non-adt: {:?}", self),
};
debug!("field_ty self: {:?} f: {:?} yields: {:?}", self, f, answer);
answer
Expand Down Expand Up @@ -94,61 +80,43 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
{
let answer = match *elem {
ProjectionElem::Deref => {
let ty = self.to_ty(tcx)
let ty = self.ty
.builtin_deref(true)
.unwrap_or_else(|| {
bug!("deref projection of non-dereferencable ty {:?}", self)
})
.ty;
PlaceTy::Ty {
ty,
}
PlaceTy::from_ty(ty)
}
ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } =>
PlaceTy::Ty {
ty: self.to_ty(tcx).builtin_index().unwrap()
},
PlaceTy::from_ty(self.ty.builtin_index().unwrap()),
ProjectionElem::Subslice { from, to } => {
let ty = self.to_ty(tcx);
PlaceTy::Ty {
ty: match ty.sty {
ty::Array(inner, size) => {
let size = size.unwrap_usize(tcx);
let len = size - (from as u64) - (to as u64);
tcx.mk_array(inner, len)
}
ty::Slice(..) => ty,
_ => {
bug!("cannot subslice non-array type: `{:?}`", self)
}
}
}
}
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());
PlaceTy::Downcast { adt_def,
substs,
variant_index: index }
PlaceTy::from_ty(match self.ty.sty {
ty::Array(inner, size) => {
let size = size.unwrap_usize(tcx);
let len = size - (from as u64) - (to as u64);
tcx.mk_array(inner, len)
}
ty::Slice(..) => self.ty,
_ => {
bug!("cannot downcast non-ADT type: `{:?}`", self)
bug!("cannot subslice non-array type: `{:?}`", self)
}
},
})
}
ProjectionElem::Downcast(_name, index) =>
PlaceTy { ty: self.ty, variant_index: Some(index) },
ProjectionElem::Field(ref f, ref fty) =>
PlaceTy::Ty { ty: handle_field(&self, f, fty) },
PlaceTy::from_ty(handle_field(&self, f, fty)),
};
debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
answer
}
}

EnumTypeFoldableImpl! {
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
(PlaceTy::Ty) { ty },
(PlaceTy::Downcast) { adt_def, substs, variant_index },
ty,
variant_index,
}
}

Expand All @@ -158,9 +126,9 @@ impl<'tcx> Place<'tcx> {
{
match *self {
Place::Base(PlaceBase::Local(index)) =>
PlaceTy::Ty { ty: local_decls.local_decls()[index].ty },
PlaceTy::from_ty(local_decls.local_decls()[index].ty),
Place::Base(PlaceBase::Static(ref data)) =>
PlaceTy::Ty { ty: data.ty },
PlaceTy::from_ty(data.ty),
Place::Projection(ref proj) =>
proj.base.ty(local_decls, tcx).projection_ty(tcx, &proj.elem),
}
Expand All @@ -185,7 +153,7 @@ impl<'tcx> Place<'tcx> {
match place {
Place::Projection(ref proj) => match proj.elem {
ProjectionElem::Field(field, _ty) => {
let base_ty = proj.base.ty(mir, *tcx).to_ty(*tcx);
let base_ty = proj.base.ty(mir, *tcx).ty;

if (base_ty.is_closure() || base_ty.is_generator()) &&
(!by_ref || mir.upvar_decls[field.index()].by_ref)
Expand Down Expand Up @@ -217,7 +185,7 @@ impl<'tcx> Rvalue<'tcx> {
tcx.mk_array(operand.ty(local_decls, tcx), count)
}
Rvalue::Ref(reg, bk, ref place) => {
let place_ty = place.ty(local_decls, tcx).to_ty(tcx);
let place_ty = place.ty(local_decls, tcx).ty;
tcx.mk_ref(reg,
ty::TypeAndMut {
ty: place_ty,
Expand All @@ -243,7 +211,7 @@ impl<'tcx> Rvalue<'tcx> {
operand.ty(local_decls, tcx)
}
Rvalue::Discriminant(ref place) => {
let ty = place.ty(local_decls, tcx).to_ty(tcx);
let ty = place.ty(local_decls, tcx).ty;
if let ty::Adt(adt_def, _) = ty.sty {
adt_def.repr.discr_type().to_ty(tcx)
} else {
Expand Down Expand Up @@ -292,7 +260,7 @@ impl<'tcx> Operand<'tcx> {
{
match self {
&Operand::Copy(ref l) |
&Operand::Move(ref l) => l.ty(local_decls, tcx).to_ty(tcx),
&Operand::Move(ref l) => l.ty(local_decls, tcx).ty,
&Operand::Constant(ref c) => c.ty,
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_codegen_ssa/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
// ZSTs don't require any actual memory access.
let elem_ty = base_ty
.projection_ty(cx.tcx(), &proj.elem)
.to_ty(cx.tcx());
.ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
if cx.layout_of(elem_ty).is_zst() {
return;
}

if let mir::ProjectionElem::Field(..) = proj.elem {
let layout = cx.layout_of(base_ty.to_ty(cx.tcx()));
let layout = cx.layout_of(base_ty.ty);
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
Expand Down Expand Up @@ -247,7 +247,7 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
PlaceContext::MutatingUse(MutatingUseContext::Drop) => {
let ty = mir::Place::Base(mir::PlaceBase::Local(local)).ty(self.fx.mir,
self.fx.cx.tcx());
let ty = self.fx.monomorphize(&ty.to_ty(self.fx.cx.tcx()));
let ty = self.fx.monomorphize(&ty.ty);

// Only need the place if we're actually dropping it.
if self.fx.cx.type_needs_drop(ty) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
target: mir::BasicBlock,
unwind: Option<mir::BasicBlock>,
) {
let ty = location.ty(self.mir, bx.tcx()).to_ty(bx.tcx());
let ty = location.ty(self.mir, bx.tcx()).ty;
let ty = self.monomorphize(&ty);
let drop_fn = monomorphize::resolve_drop_in_place(bx.tcx(), ty);

Expand Down
6 changes: 3 additions & 3 deletions src/librustc_codegen_ssa/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::ProjectionElem::Subslice { from, to } => {
let mut subslice = cg_base.project_index(bx,
bx.cx().const_usize(from as u64));
let projected_ty = PlaceTy::Ty { ty: cg_base.layout.ty }
.projection_ty(tcx, &projection.elem).to_ty(tcx);
let projected_ty = PlaceTy::from_ty(cg_base.layout.ty)
.projection_ty(tcx, &projection.elem).ty;
subslice.layout = bx.cx().layout_of(self.monomorphize(&projected_ty));

if subslice.layout.is_unsized() {
Expand Down Expand Up @@ -523,6 +523,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn monomorphized_place_ty(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> {
let tcx = self.cx.tcx();
let place_ty = place.ty(self.mir, tcx);
self.monomorphize(&place_ty.to_ty(tcx))
self.monomorphize(&place_ty.ty)
}
}
15 changes: 7 additions & 8 deletions src/librustc_mir/borrow_check/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
);
}

let ty = used_place.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let ty = used_place.ty(self.mir, self.infcx.tcx).ty;
let needs_note = match ty.sty {
ty::Closure(id, _) => {
let tables = self.infcx.tcx.typeck_tables_of(id);
Expand All @@ -217,7 +217,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let mpi = self.move_data.moves[move_out_indices[0]].path;
let place = &self.move_data.move_paths[mpi].place;

let ty = place.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let ty = place.ty(self.mir, self.infcx.tcx).ty;
let opt_name = self.describe_place_with_options(place, IncludingDowncast(true));
let note_msg = match opt_name {
Some(ref name) => format!("`{}`", name),
Expand Down Expand Up @@ -601,8 +601,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// Define a small closure that we can use to check if the type of a place
// is a union.
let is_union = |place: &Place<'tcx>| -> bool {
place.ty(self.mir, self.infcx.tcx)
.to_ty(self.infcx.tcx)
place.ty(self.mir, self.infcx.tcx).ty
.ty_adt_def()
.map(|adt| adt.is_union())
.unwrap_or(false)
Expand Down Expand Up @@ -651,7 +650,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {

// Also compute the name of the union type, eg. `Foo` so we
// can add a helpful note with it.
let ty = base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let ty = base.ty(self.mir, self.infcx.tcx).ty;

return Some((desc_base, desc_first, desc_second, ty.to_string()));
},
Expand Down Expand Up @@ -1777,7 +1776,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Place::Projection(ref proj) => match proj.elem {
ProjectionElem::Deref => self.describe_field(&proj.base, field),
ProjectionElem::Downcast(_, variant_index) => {
let base_ty = base.ty(self.mir, self.infcx.tcx).to_ty();
let base_ty = base.ty(self.mir, self.infcx.tcx).ty;
self.describe_field_from_ty(&base_ty, field, Some(variant_index))
}
ProjectionElem::Field(_, field_type) => {
Expand Down Expand Up @@ -1878,15 +1877,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
StorageDeadOrDrop::LocalStorageDead
| StorageDeadOrDrop::BoxedStorageDead => {
assert!(
base.ty(self.mir, tcx).to_ty(tcx).is_box(),
base.ty(self.mir, tcx).ty.is_box(),
"Drop of value behind a reference or raw pointer"
);
StorageDeadOrDrop::BoxedStorageDead
}
StorageDeadOrDrop::Destructor(_) => base_access,
},
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
let base_ty = base.ty(self.mir, tcx).to_ty(tcx);
let base_ty = base.ty(self.mir, tcx).ty;
match base_ty.sty {
ty::Adt(def, _) if def.has_dtor(tcx) => {
// Report the outermost adt with a destructor
Expand Down
9 changes: 4 additions & 5 deletions src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
let drop_place_ty = drop_place.ty(self.mir, self.infcx.tcx);

// Erase the regions.
let drop_place_ty = self.infcx.tcx.erase_regions(&drop_place_ty)
.to_ty(self.infcx.tcx);
let drop_place_ty = self.infcx.tcx.erase_regions(&drop_place_ty).ty;

// "Lift" into the gcx -- once regions are erased, this type should be in the
// global arenas; this "lift" operation basically just asserts that is true, but
Expand Down Expand Up @@ -1641,7 +1640,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// assigning to `P.f` requires `P` itself
// be already initialized
let tcx = self.infcx.tcx;
match base.ty(self.mir, tcx).to_ty(tcx).sty {
match base.ty(self.mir, tcx).ty.sty {
ty::Adt(def, _) if def.has_dtor(tcx) => {
self.check_if_path_or_subpath_is_moved(
context, InitializationRequiringAction::Assignment,
Expand Down Expand Up @@ -1746,7 +1745,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// no move out from an earlier location) then this is an attempt at initialization
// of the union - we should error in that case.
let tcx = this.infcx.tcx;
if let ty::TyKind::Adt(def, _) = base.ty(this.mir, tcx).to_ty(tcx).sty {
if let ty::TyKind::Adt(def, _) = base.ty(this.mir, tcx).ty.sty {
if def.is_union() {
if this.move_data.path_map[mpi].iter().any(|moi| {
this.move_data.moves[*moi].source.is_predecessor_of(
Expand Down Expand Up @@ -2007,7 +2006,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Place::Projection(ref proj) => {
match proj.elem {
ProjectionElem::Deref => {
let base_ty = proj.base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let base_ty = proj.base.ty(self.mir, self.infcx.tcx).ty;

// Check the kind of deref to decide
match base_ty.sty {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_mir/borrow_check/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// Inspect the type of the content behind the
// borrow to provide feedback about why this
// was a move rather than a copy.
let ty = place.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let ty = place.ty(self.mir, self.infcx.tcx).ty;
let is_upvar_field_projection =
self.prefixes(&original_path, PrefixSet::All)
.any(|p| p.is_upvar_field_projection(self.mir, &self.infcx.tcx)
Expand Down Expand Up @@ -530,7 +530,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// We're only interested in assignments (in particular, where the
// assignment came from - was it an `Rc` or `Arc`?).
if let StatementKind::Assign(_, box Rvalue::Ref(_, _, source)) = &stmt.kind {
let ty = source.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let ty = source.ty(self.mir, self.infcx.tcx).ty;
let ty = match ty.sty {
ty::TyKind::Ref(_, ty, _) => ty,
_ => ty,
Expand All @@ -555,7 +555,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
_ => continue,
};

let ty = source.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let ty = source.ty(self.mir, self.infcx.tcx).ty;
let ty = match ty.sty {
ty::TyKind::Ref(_, ty, _) => ty,
_ => ty,
Expand All @@ -581,7 +581,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
base,
elem: ProjectionElem::Deref,
}) = place {
if base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx).is_unsafe_ptr() {
if base.ty(self.mir, self.infcx.tcx).ty.is_unsafe_ptr() {
return BorrowedContentSource::DerefRawPointer;
}
}
Expand Down
Loading

0 comments on commit 4122d22

Please sign in to comment.