Skip to content

Commit

Permalink
auto merge of #11055 : pcwalton/rust/placement-box, r=pcwalton
Browse files Browse the repository at this point in the history
  • Loading branch information
bors committed Jan 10, 2014
2 parents d28317d + e127115 commit ff3d5d4
Show file tree
Hide file tree
Showing 22 changed files with 296 additions and 42 deletions.
4 changes: 4 additions & 0 deletions src/librustc/middle/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ impl CFGBuilder {
self.straightline(expr, pred, [l, r])
}

ast::ExprBox(p, e) => {
self.straightline(expr, pred, [p, e])
}

ast::ExprAddrOf(_, e) |
ast::ExprDoBody(e) |
ast::ExprCast(e, _) |
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/middle/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,11 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
self.walk_expr(e, in_out, loop_scopes);
}

ast::ExprBox(s, e) => {
self.walk_expr(s, in_out, loop_scopes);
self.walk_expr(e, in_out, loop_scopes);
}

ast::ExprInlineAsm(ref inline_asm) => {
for &(_, expr) in inline_asm.inputs.iter() {
self.walk_expr(expr, in_out, loop_scopes);
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub fn collect_language_items(crate: &ast::Crate,
}

lets_do_this! {
There are 37 lang items.
There are 40 lang items.

// ID, Variant name, Name, Method name;
0, FreezeTraitLangItem, "freeze", freeze_trait;
Expand Down Expand Up @@ -256,5 +256,9 @@ lets_do_this! {
35, TypeIdLangItem, "type_id", type_id;

36, EhPersonalityLangItem, "eh_personality", eh_personality_fn;

37, ManagedHeapLangItem, "managed_heap", managed_heap;
38, ExchangeHeapLangItem, "exchange_heap", exchange_heap;
39, GcLangItem, "gc", gc;
}

7 changes: 4 additions & 3 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) |
ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) |
ExprStruct(..) | ExprRepeat(..) | ExprParen(..) |
ExprInlineAsm(..) => {
ExprInlineAsm(..) | ExprBox(..) => {
visit::walk_expr(v, expr, this);
}
}
Expand Down Expand Up @@ -1252,7 +1252,8 @@ impl Liveness {
}

ExprIndex(_, l, r) |
ExprBinary(_, _, l, r) => {
ExprBinary(_, _, l, r) |
ExprBox(l, r) => {
self.propagate_through_exprs([l, r], succ)
}

Expand Down Expand Up @@ -1546,7 +1547,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprPath(..) |
ExprSelf(..) => {
ExprSelf(..) | ExprBox(..) => {
visit::walk_expr(this, expr, ());
}
ExprForLoop(..) => fail!("non-desugared expr_for_loop")
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ impl mem_categorization_ctxt {
ast::ExprBlock(..) | ast::ExprLoop(..) | ast::ExprMatch(..) |
ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
ast::ExprInlineAsm(..) => {
ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
return self.cat_rvalue_node(expr, expr_ty);
}

Expand Down
5 changes: 5 additions & 0 deletions src/librustc/middle/moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,11 @@ impl VisitContext {
self.use_expr(base, comp_mode);
}

ExprBox(place, base) => {
self.use_expr(place, comp_mode);
self.use_expr(base, comp_mode);
}

ExprMac(..) => {
self.tcx.sess.span_bug(
expr.span,
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2613,6 +2613,11 @@ fn populate_scope_map(cx: &CrateContext,
ast::ExprField(@ref sub_exp, _, _) |
ast::ExprParen(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),

ast::ExprBox(@ref place, @ref sub_expr) => {
walk_expr(cx, place, scope_stack, scope_map);
walk_expr(cx, sub_expr, scope_stack, scope_map);
}

ast::ExprRet(exp_opt) => match exp_opt {
Some(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
None => ()
Expand Down
105 changes: 77 additions & 28 deletions src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,14 @@ fn trans_rvalue_datum_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
return tvec::trans_uniq_or_managed_vstore(bcx, heap,
expr, contents);
}
ast::ExprBox(_, contents) => {
// Special case for `~T`. (The other case, for GC, is handled in
// `trans_rvalue_dps_unadjusted`.)
let box_ty = expr_ty(bcx, expr);
let contents_ty = expr_ty(bcx, contents);
let heap = heap_for_unique(bcx, contents_ty);
return trans_boxed_expr(bcx, box_ty, contents, contents_ty, heap)
}
ast::ExprLit(lit) => {
return trans_immediate_lit(bcx, expr, *lit);
}
Expand Down Expand Up @@ -828,6 +836,11 @@ fn trans_rvalue_dps_unadjusted<'a>(
ast::ExprAssignOp(callee_id, op, dst, src) => {
return trans_assign_op(bcx, expr, callee_id, op, dst, src);
}
ast::ExprBox(_, contents) => {
// Special case for `Gc<T>` for now. The other case, for unique
// pointers, is handled in `trans_rvalue_datum_unadjusted`.
return trans_gc(bcx, expr, contents, dest)
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,
Expand Down Expand Up @@ -1463,35 +1476,35 @@ fn trans_unary_datum<'a>(
trans_unary_datum()")
}
};
}

fn trans_boxed_expr<'a>(
bcx: &'a Block<'a>,
box_ty: ty::t,
contents: &ast::Expr,
contents_ty: ty::t,
heap: heap)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_boxed_expr");
if heap == heap_exchange {
let llty = type_of::type_of(bcx.ccx(), contents_ty);
let size = llsize_of(bcx.ccx(), llty);
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
heap_exchange, size);
add_clean_free(bcx, val, heap_exchange);
let bcx = trans_into(bcx, contents, SaveIn(val));
revoke_clean(bcx, val);
return immediate_rvalue_bcx(bcx, val, box_ty);
} else {
let base::MallocResult {
bcx,
smart_ptr: bx,
body
} = base::malloc_general(bcx, contents_ty, heap);
add_clean_free(bcx, bx, heap);
let bcx = trans_into(bcx, contents, SaveIn(body));
revoke_clean(bcx, bx);
return immediate_rvalue_bcx(bcx, bx, box_ty);
}
fn trans_boxed_expr<'a>(
bcx: &'a Block<'a>,
box_ty: ty::t,
contents: &ast::Expr,
contents_ty: ty::t,
heap: heap)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_boxed_expr");
if heap == heap_exchange {
let llty = type_of::type_of(bcx.ccx(), contents_ty);
let size = llsize_of(bcx.ccx(), llty);
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
heap_exchange, size);
add_clean_free(bcx, val, heap_exchange);
let bcx = trans_into(bcx, contents, SaveIn(val));
revoke_clean(bcx, val);
return immediate_rvalue_bcx(bcx, val, box_ty);
} else {
let base::MallocResult {
bcx,
smart_ptr: bx,
body
} = base::malloc_general(bcx, contents_ty, heap);
add_clean_free(bcx, bx, heap);
let bcx = trans_into(bcx, contents, SaveIn(body));
revoke_clean(bcx, bx);
return immediate_rvalue_bcx(bcx, bx, box_ty);
}
}

Expand All @@ -1507,6 +1520,42 @@ fn trans_addr_of<'a>(
return immediate_rvalue_bcx(bcx, llval, expr_ty(bcx, expr));
}

pub fn trans_gc<'a>(
mut bcx: &'a Block<'a>,
expr: &ast::Expr,
contents: &ast::Expr,
dest: Dest)
-> &'a Block<'a> {
let contents_ty = expr_ty(bcx, contents);
let box_ty = ty::mk_box(bcx.tcx(), contents_ty);
let expr_ty = expr_ty(bcx, expr);

let addr = match dest {
Ignore => {
return trans_boxed_expr(bcx,
box_ty,
contents,
contents_ty,
heap_managed).bcx
}
SaveIn(addr) => addr,
};

let repr = adt::represent_type(bcx.ccx(), expr_ty);
adt::trans_start_init(bcx, repr, addr, 0);
let field_dest = adt::trans_field_ptr(bcx, repr, addr, 0, 0);
let contents_datum_block = trans_boxed_expr(bcx,
box_ty,
contents,
contents_ty,
heap_managed);
bcx = contents_datum_block.bcx;
bcx = contents_datum_block.datum.move_to(bcx, INIT, field_dest);

// Next, wrap it up in the struct.
bcx
}

// Important to get types for both lhs and rhs, because one might be _|_
// and the other not.
fn trans_eager_binop<'a>(
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/middle/trans/tvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use back::abi;
use lib;
use lib::llvm::{llvm, ValueRef};
use middle::lang_items::StrDupUniqFnLangItem;
use middle::trans::base;
use middle::trans::base::*;
use middle::trans::base;
use middle::trans::build::*;
use middle::trans::callee;
use middle::trans::common::*;
Expand All @@ -23,14 +23,12 @@ use middle::trans::expr::{Dest, Ignore, SaveIn};
use middle::trans::expr;
use middle::trans::glue;
use middle::trans::machine::{llsize_of, nonzero_llsize_of, llsize_of_alloc};
use middle::trans::type_::Type;
use middle::trans::type_of;
use middle::ty;
use util::common::indenter;
use util::ppaux::ty_to_str;

use middle::trans::type_::Type;

use std::option::None;
use syntax::ast;
use syntax::codemap;

Expand Down Expand Up @@ -689,3 +687,4 @@ pub fn iter_vec_unboxed<'r,
let dataptr = get_dataptr(bcx, body_ptr);
return iter_vec_raw(bcx, dataptr, vec_ty, fill, f);
}

16 changes: 15 additions & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use driver::session;
use metadata::csearch;
use metadata;
use middle::const_eval;
use middle::lang_items::{ExchangeHeapLangItem, OpaqueStructLangItem};
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
use middle::lang_items::OpaqueStructLangItem;
use middle::freevars;
use middle::resolve;
use middle::resolve_lifetime;
Expand Down Expand Up @@ -3241,6 +3241,20 @@ pub fn expr_kind(tcx: ctxt,
RvalueDatumExpr
}

ast::ExprBox(place, _) => {
// Special case `~T` for now:
let def_map = tcx.def_map.borrow();
let definition = match def_map.get().find(&place.id) {
Some(&def) => def,
None => fail!("no def for place"),
};
let def_id = ast_util::def_id_of_def(definition);
match tcx.lang_items.items[ExchangeHeapLangItem as uint] {
Some(item_def_id) if def_id == item_def_id => RvalueDatumExpr,
Some(_) | None => RvalueDpsExpr,
}
}

ast::ExprParen(e) => expr_kind(tcx, method_map, e),

ast::ExprMac(..) => {
Expand Down
71 changes: 70 additions & 1 deletion src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ type parameter).


use middle::const_eval;
use middle::lang_items::{ExchangeHeapLangItem, GcLangItem};
use middle::lang_items::{ManagedHeapLangItem};
use middle::lint::unreachable_code;
use middle::pat_util::pat_id_map;
use middle::pat_util;
use middle::lint::unreachable_code;
use middle::subst::Subst;
use middle::ty::{FnSig, VariantInfo};
use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
Expand Down Expand Up @@ -2679,6 +2681,73 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_ty(id, typ);
}

ast::ExprBox(place, subexpr) => {
check_expr(fcx, place);
check_expr(fcx, subexpr);

let mut checked = false;
match place.node {
ast::ExprPath(ref path) => {
// XXX(pcwalton): For now we hardcode the two permissible
// places: the exchange heap and the managed heap.
let definition = lookup_def(fcx, path.span, place.id);
let def_id = ast_util::def_id_of_def(definition);
match tcx.lang_items.items[ExchangeHeapLangItem as uint] {
Some(item_def_id) if def_id == item_def_id => {
fcx.write_ty(id, ty::mk_uniq(tcx, ty::mt {
ty: fcx.expr_ty(subexpr),
mutbl: ast::MutImmutable,
}));
checked = true
}
Some(_) | None => {}
}
if !checked {
match tcx.lang_items
.items[ManagedHeapLangItem as uint] {
Some(item_def_id) if def_id == item_def_id => {
// Assign the magic `Gc<T>` struct.
let gc_struct_id =
match tcx.lang_items
.require(GcLangItem) {
Ok(id) => id,
Err(msg) => {
tcx.sess.span_err(expr.span, msg);
ast::DefId {
crate: ast::CRATE_NODE_ID,
node: ast::DUMMY_NODE_ID,
}
}
};
let regions =
ty::NonerasedRegions(opt_vec::Empty);
let sty = ty::mk_struct(tcx,
gc_struct_id,
substs {
self_ty: None,
tps: ~[
fcx.expr_ty(
subexpr)
],
regions: regions,
});
fcx.write_ty(id, sty);
checked = true
}
Some(_) | None => {}
}
}
}
_ => {}
}

if !checked {
tcx.sess.span_err(expr.span,
"only the managed heap and exchange heap are \
currently supported")
}
}

ast::ExprLit(lit) => {
let typ = check_lit(fcx, lit);
fcx.write_ty(id, typ);
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,7 @@ pub mod guarantor {
ast::ExprAddrOf(..) |
ast::ExprBinary(..) |
ast::ExprVstore(..) |
ast::ExprBox(..) |
ast::ExprBreak(..) |
ast::ExprAgain(..) |
ast::ExprRet(..) |
Expand Down
Loading

0 comments on commit ff3d5d4

Please sign in to comment.