Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate array drop glue using MIR #41917

Merged
merged 11 commits into from
May 28, 2017
10 changes: 8 additions & 2 deletions src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx>
mir::Rvalue::Discriminant(ref lvalue) => {
lvalue.hash_stable(hcx, hasher);
}
mir::Rvalue::Box(ty) => {
mir::Rvalue::NullaryOp(op, ty) => {
op.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
mir::Rvalue::Aggregate(ref kind, ref operands) => {
Expand Down Expand Up @@ -374,14 +375,19 @@ impl_stable_hash_for!(enum mir::BinOp {
Le,
Ne,
Ge,
Gt
Gt,
Offset
});

impl_stable_hash_for!(enum mir::UnOp {
Not,
Neg
});

impl_stable_hash_for!(enum mir::NullOp {
Box,
SizeOf
});

impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
#![cfg_attr(stage0, feature(staged_api))]
#![cfg_attr(stage0, feature(loop_break_value))]

#![recursion_limit="128"]
#![recursion_limit="192"]

extern crate arena;
extern crate core;
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ pub trait CrateStore {

// flags
fn is_const_fn(&self, did: DefId) -> bool;
fn is_default_impl(&self, impl_did: DefId) -> bool;
fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;

Expand Down Expand Up @@ -364,7 +363,6 @@ impl CrateStore for DummyCrateStore {

// flags
fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }

Expand Down
20 changes: 14 additions & 6 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,7 @@ pub enum Rvalue<'tcx> {
BinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
CheckedBinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),

NullaryOp(NullOp, Ty<'tcx>),
UnaryOp(UnOp, Operand<'tcx>),

/// Read the discriminant of an ADT.
Expand All @@ -1054,9 +1055,6 @@ pub enum Rvalue<'tcx> {
/// be defined to return, say, a 0) if ADT is not an enum.
Discriminant(Lvalue<'tcx>),

/// Creates an *uninitialized* Box
Box(Ty<'tcx>),

/// Create an aggregate value, like a tuple or struct. This is
/// only needed because we want to distinguish `dest = Foo { x:
/// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
Expand Down Expand Up @@ -1132,6 +1130,8 @@ pub enum BinOp {
Ge,
/// The `>` operator (greater than)
Gt,
/// The `ptr.offset` operator
Offset,
}

impl BinOp {
Expand All @@ -1144,6 +1144,14 @@ impl BinOp {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum NullOp {
/// Return the size of a value of that type
SizeOf,
/// Create a new uninitialized box for a value of that type
Box,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum UnOp {
/// The `!` operator for logical inversion
Expand All @@ -1167,7 +1175,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
}
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
Box(ref t) => write!(fmt, "Box({:?})", t),
NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
Ref(_, borrow_kind, ref lv) => {
let kind_str = match borrow_kind {
BorrowKind::Shared => "",
Expand Down Expand Up @@ -1601,7 +1609,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder)),
UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
Discriminant(ref lval) => Discriminant(lval.fold_with(folder)),
Box(ty) => Box(ty.fold_with(folder)),
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
Aggregate(ref kind, ref fields) => {
let kind = box match **kind {
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
Expand Down Expand Up @@ -1629,7 +1637,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
rhs.visit_with(visitor) || lhs.visit_with(visitor),
UnaryOp(_, ref val) => val.visit_with(visitor),
Discriminant(ref lval) => lval.visit_with(visitor),
Box(ty) => ty.visit_with(visitor),
NullaryOp(_, ty) => ty.visit_with(visitor),
Aggregate(ref kind, ref fields) => {
(match **kind {
AggregateKind::Array(ty) => ty.visit_with(visitor),
Expand Down
13 changes: 7 additions & 6 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ impl<'tcx> Rvalue<'tcx> {
let ty = op.ty(tcx, lhs_ty, rhs_ty);
tcx.intern_tup(&[ty, tcx.types.bool], false)
}
Rvalue::UnaryOp(_, ref operand) => {
Rvalue::UnaryOp(UnOp::Not, ref operand) |
Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
operand.ty(mir, tcx)
}
Rvalue::Discriminant(ref lval) => {
Expand All @@ -179,9 +180,8 @@ impl<'tcx> Rvalue<'tcx> {
bug!("Rvalue::Discriminant on Lvalue of type {:?}", ty);
}
}
Rvalue::Box(t) => {
tcx.mk_box(t)
}
Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
Rvalue::Aggregate(ref ak, ref ops) => {
match **ak {
AggregateKind::Array(ty) => {
Expand Down Expand Up @@ -227,7 +227,7 @@ impl<'tcx> BinOp {
assert_eq!(lhs_ty, rhs_ty);
lhs_ty
}
&BinOp::Shl | &BinOp::Shr => {
&BinOp::Shl | &BinOp::Shr | &BinOp::Offset => {
lhs_ty // lhs_ty can be != rhs_ty
}
&BinOp::Eq | &BinOp::Lt | &BinOp::Le |
Expand Down Expand Up @@ -270,7 +270,8 @@ impl BinOp {
BinOp::Lt => hir::BinOp_::BiLt,
BinOp::Gt => hir::BinOp_::BiGt,
BinOp::Le => hir::BinOp_::BiLe,
BinOp::Ge => hir::BinOp_::BiGe
BinOp::Ge => hir::BinOp_::BiGe,
BinOp::Offset => unreachable!()
}
}
}
2 changes: 1 addition & 1 deletion src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ macro_rules! make_mir_visitor {
self.visit_lvalue(lvalue, LvalueContext::Inspect, location);
}

Rvalue::Box(ref $($mutability)* ty) => {
Rvalue::NullaryOp(_op, ref $($mutability)* ty) => {
self.visit_ty(ty);
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/item_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

// Always use types for non-local impls, where types are always
// available, and filename/line-number is mostly uninteresting.
let use_types = !impl_def_id.is_local() || {
let use_types = !self.is_default_impl(impl_def_id) && (!impl_def_id.is_local() || {
// Otherwise, use filename/line-number if forced.
let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
!force_no_types && {
// Otherwise, use types if we can query them without inducing a cycle.
ty::queries::impl_trait_ref::try_get(self, DUMMY_SP, impl_def_id).is_ok() &&
ty::queries::type_of::try_get(self, DUMMY_SP, impl_def_id).is_ok()
}
};
});

if !use_types {
return self.push_impl_path_fallback(buffer, impl_def_id);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,9 @@ define_maps! { <'tcx>
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
[] is_foreign_item: IsForeignItem(DefId) -> bool,

/// True if this is a default impl (aka impl Foo for ..)
[] is_default_impl: ItemSignature(DefId) -> bool,

/// Get a map with the variance of every item; use `item_variance`
/// instead.
[] crate_variances: crate_variances(CrateNum) -> Rc<ty::CrateVariancesMap>,
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
})
}

pub fn const_usize(&self, val: u16) -> ConstInt {
match self.sess.target.uint_type {
ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(val as u16)),
ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(val as u32)),
ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64(val as u64)),
_ => bug!(),
}
}
}

pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {
Expand Down
13 changes: 6 additions & 7 deletions src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc::util::nodemap::FxHashMap;
use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc_data_structures::indexed_vec::Idx;
use rustc_mir::util::patch::MirPatch;
use rustc_mir::util::elaborate_drops::{DropFlagState, elaborate_drop};
use rustc_mir::util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop};
use rustc_mir::util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode};
use syntax::ast;
use syntax_pos::Span;
Expand Down Expand Up @@ -399,14 +399,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
ctxt: self
},
terminator.source_info,
data.is_cleanup,
location,
path,
target,
if data.is_cleanup {
None
Unwind::InCleanup
} else {
Some(Option::unwrap_or(unwind, resume_block))
Unwind::To(Option::unwrap_or(unwind, resume_block))
},
bb)
}
Expand Down Expand Up @@ -455,6 +454,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let bb = loc.block;
let data = &self.mir[bb];
let terminator = data.terminator();
assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");

let assign = Statement {
kind: StatementKind::Assign(location.clone(), Rvalue::Use(value.clone())),
Expand All @@ -477,7 +477,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
kind: TerminatorKind::Goto { target: target },
..*terminator
}),
is_cleanup: data.is_cleanup,
is_cleanup: false,
});

match self.move_data().rev_lookup.find(location) {
Expand All @@ -491,11 +491,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
ctxt: self
},
terminator.source_info,
data.is_cleanup,
location,
path,
target,
Some(unwind),
Unwind::To(unwind),
bb);
on_all_children_bits(self.tcx, self.mir, self.move_data(), path, |child| {
self.set_drop_flag(Location { block: target, statement_index: 0 },
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/mir/gather_moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
Rvalue::Ref(..) |
Rvalue::Discriminant(..) |
Rvalue::Len(..) |
Rvalue::Box(..) => {
Rvalue::NullaryOp(NullOp::SizeOf, _) |
Rvalue::NullaryOp(NullOp::Box, _) => {
// This returns an rvalue with uninitialized contents. We can't
// move out of it here because it is an rvalue - assignments always
// completely initialize their lvalue.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_borrowck/borrowck/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
attributes: &[ast::Attribute]) {
let tcx = bcx.tcx;
let def_id = tcx.hir.local_def_id(id);
debug!("borrowck_mir({}) UNIMPLEMENTED", tcx.item_path_str(def_id));
debug!("borrowck_mir({:?}) UNIMPLEMENTED", def_id);

// It is safe for us to borrow `mir_validated()`: `optimized_mir`
// steals it, but it forces the `borrowck` query.
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_data_structures/indexed_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ impl<I: Idx, T> IndexMut<I> for IndexVec<I, T> {
}
}

impl<I: Idx, T> Default for IndexVec<I, T> {
#[inline]
fn default() -> Self {
Self::new()
}
}

impl<I: Idx, T> Extend<T> for IndexVec<I, T> {
#[inline]
fn extend<J: IntoIterator<Item = T>>(&mut self, iter: J) {
Expand Down
10 changes: 3 additions & 7 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ provide! { <'tcx> tcx, def_id, cdata
closure_type => { cdata.closure_ty(def_id.index, tcx) }
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
is_default_impl => { cdata.is_default_impl(def_id.index) }
describe_def => { cdata.get_def(def_id.index) }
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
stability => { cdata.get_stability(def_id.index) }
Expand Down Expand Up @@ -176,11 +177,6 @@ impl CrateStore for cstore::CStore {
self.get_crate_data(did.krate).is_const_fn(did.index)
}

fn is_default_impl(&self, impl_did: DefId) -> bool {
self.dep_graph.read(DepNode::MetaData(impl_did));
self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index)
}

fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool
{
self.do_is_statically_included_foreign_item(def_id)
Expand Down Expand Up @@ -403,7 +399,7 @@ impl CrateStore for cstore::CStore {
}

self.dep_graph.read(DepNode::MetaData(def_id));
debug!("item_body({}): inlining item", tcx.item_path_str(def_id));
debug!("item_body({:?}): inlining item", def_id);

self.get_crate_data(def_id.krate).item_body(tcx, def_id.index)
}
Expand Down Expand Up @@ -515,4 +511,4 @@ impl CrateStore for cstore::CStore {
drop(visible_parent_map);
self.visible_parent_map.borrow()
}
}
}
3 changes: 2 additions & 1 deletion src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let value = this.hir.mirror(value);
let result = this.temp(expr.ty, expr_span);
// to start, malloc some memory of suitable type (thus far, uninitialized):
this.cfg.push_assign(block, source_info, &result, Rvalue::Box(value.ty));
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
this.cfg.push_assign(block, source_info, &result, box_);
this.in_scope(value_extents, block, |this| {
// schedule a shallow free of that memory, lest we unwind:
this.schedule_box_free(expr_span, value_extents, &result, value.ty);
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_mir/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,10 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
elaborate_drops::elaborate_drop(
&mut elaborator,
source_info,
false,
&dropee,
(),
return_block,
Some(resume_block),
elaborate_drops::Unwind::To(resume_block),
START_BLOCK
);
elaborator.patch
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/erase_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
Rvalue::CheckedBinaryOp(..) |
Rvalue::UnaryOp(..) |
Rvalue::Discriminant(..) |
Rvalue::Box(..) |
Rvalue::NullaryOp(..) |
Rvalue::Aggregate(..) => {
// These variants don't contain regions.
}
Expand Down
Loading