Skip to content

Commit ff3d5d4

Browse files
committed
auto merge of #11055 : pcwalton/rust/placement-box, r=pcwalton
r? @nikomatsakis
2 parents d28317d + e127115 commit ff3d5d4

22 files changed

+296
-42
lines changed

src/librustc/middle/cfg/construct.rs

+4
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ impl CFGBuilder {
394394
self.straightline(expr, pred, [l, r])
395395
}
396396

397+
ast::ExprBox(p, e) => {
398+
self.straightline(expr, pred, [p, e])
399+
}
400+
397401
ast::ExprAddrOf(_, e) |
398402
ast::ExprDoBody(e) |
399403
ast::ExprCast(e, _) |

src/librustc/middle/dataflow.rs

+5
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,11 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
720720
self.walk_expr(e, in_out, loop_scopes);
721721
}
722722

723+
ast::ExprBox(s, e) => {
724+
self.walk_expr(s, in_out, loop_scopes);
725+
self.walk_expr(e, in_out, loop_scopes);
726+
}
727+
723728
ast::ExprInlineAsm(ref inline_asm) => {
724729
for &(_, expr) in inline_asm.inputs.iter() {
725730
self.walk_expr(expr, in_out, loop_scopes);

src/librustc/middle/lang_items.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ pub fn collect_language_items(crate: &ast::Crate,
207207
}
208208

209209
lets_do_this! {
210-
There are 37 lang items.
210+
There are 40 lang items.
211211

212212
// ID, Variant name, Name, Method name;
213213
0, FreezeTraitLangItem, "freeze", freeze_trait;
@@ -256,5 +256,9 @@ lets_do_this! {
256256
35, TypeIdLangItem, "type_id", type_id;
257257

258258
36, EhPersonalityLangItem, "eh_personality", eh_personality_fn;
259+
260+
37, ManagedHeapLangItem, "managed_heap", managed_heap;
261+
38, ExchangeHeapLangItem, "exchange_heap", exchange_heap;
262+
39, GcLangItem, "gc", gc;
259263
}
260264

src/librustc/middle/liveness.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
556556
ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) |
557557
ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) |
558558
ExprStruct(..) | ExprRepeat(..) | ExprParen(..) |
559-
ExprInlineAsm(..) => {
559+
ExprInlineAsm(..) | ExprBox(..) => {
560560
visit::walk_expr(v, expr, this);
561561
}
562562
}
@@ -1252,7 +1252,8 @@ impl Liveness {
12521252
}
12531253

12541254
ExprIndex(_, l, r) |
1255-
ExprBinary(_, _, l, r) => {
1255+
ExprBinary(_, _, l, r) |
1256+
ExprBox(l, r) => {
12561257
self.propagate_through_exprs([l, r], succ)
12571258
}
12581259

@@ -1546,7 +1547,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
15461547
ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
15471548
ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
15481549
ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprPath(..) |
1549-
ExprSelf(..) => {
1550+
ExprSelf(..) | ExprBox(..) => {
15501551
visit::walk_expr(this, expr, ());
15511552
}
15521553
ExprForLoop(..) => fail!("non-desugared expr_for_loop")

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ impl mem_categorization_ctxt {
438438
ast::ExprBlock(..) | ast::ExprLoop(..) | ast::ExprMatch(..) |
439439
ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
440440
ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
441-
ast::ExprInlineAsm(..) => {
441+
ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
442442
return self.cat_rvalue_node(expr, expr_ty);
443443
}
444444

src/librustc/middle/moves.rs

+5
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,11 @@ impl VisitContext {
591591
self.use_expr(base, comp_mode);
592592
}
593593

594+
ExprBox(place, base) => {
595+
self.use_expr(place, comp_mode);
596+
self.use_expr(base, comp_mode);
597+
}
598+
594599
ExprMac(..) => {
595600
self.tcx.sess.span_bug(
596601
expr.span,

src/librustc/middle/trans/debuginfo.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2613,6 +2613,11 @@ fn populate_scope_map(cx: &CrateContext,
26132613
ast::ExprField(@ref sub_exp, _, _) |
26142614
ast::ExprParen(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
26152615

2616+
ast::ExprBox(@ref place, @ref sub_expr) => {
2617+
walk_expr(cx, place, scope_stack, scope_map);
2618+
walk_expr(cx, sub_expr, scope_stack, scope_map);
2619+
}
2620+
26162621
ast::ExprRet(exp_opt) => match exp_opt {
26172622
Some(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
26182623
None => ()

src/librustc/middle/trans/expr.rs

+77-28
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,14 @@ fn trans_rvalue_datum_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
619619
return tvec::trans_uniq_or_managed_vstore(bcx, heap,
620620
expr, contents);
621621
}
622+
ast::ExprBox(_, contents) => {
623+
// Special case for `~T`. (The other case, for GC, is handled in
624+
// `trans_rvalue_dps_unadjusted`.)
625+
let box_ty = expr_ty(bcx, expr);
626+
let contents_ty = expr_ty(bcx, contents);
627+
let heap = heap_for_unique(bcx, contents_ty);
628+
return trans_boxed_expr(bcx, box_ty, contents, contents_ty, heap)
629+
}
622630
ast::ExprLit(lit) => {
623631
return trans_immediate_lit(bcx, expr, *lit);
624632
}
@@ -828,6 +836,11 @@ fn trans_rvalue_dps_unadjusted<'a>(
828836
ast::ExprAssignOp(callee_id, op, dst, src) => {
829837
return trans_assign_op(bcx, expr, callee_id, op, dst, src);
830838
}
839+
ast::ExprBox(_, contents) => {
840+
// Special case for `Gc<T>` for now. The other case, for unique
841+
// pointers, is handled in `trans_rvalue_datum_unadjusted`.
842+
return trans_gc(bcx, expr, contents, dest)
843+
}
831844
_ => {
832845
bcx.tcx().sess.span_bug(
833846
expr.span,
@@ -1463,35 +1476,35 @@ fn trans_unary_datum<'a>(
14631476
trans_unary_datum()")
14641477
}
14651478
};
1479+
}
14661480

1467-
fn trans_boxed_expr<'a>(
1468-
bcx: &'a Block<'a>,
1469-
box_ty: ty::t,
1470-
contents: &ast::Expr,
1471-
contents_ty: ty::t,
1472-
heap: heap)
1473-
-> DatumBlock<'a> {
1474-
let _icx = push_ctxt("trans_boxed_expr");
1475-
if heap == heap_exchange {
1476-
let llty = type_of::type_of(bcx.ccx(), contents_ty);
1477-
let size = llsize_of(bcx.ccx(), llty);
1478-
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
1479-
heap_exchange, size);
1480-
add_clean_free(bcx, val, heap_exchange);
1481-
let bcx = trans_into(bcx, contents, SaveIn(val));
1482-
revoke_clean(bcx, val);
1483-
return immediate_rvalue_bcx(bcx, val, box_ty);
1484-
} else {
1485-
let base::MallocResult {
1486-
bcx,
1487-
smart_ptr: bx,
1488-
body
1489-
} = base::malloc_general(bcx, contents_ty, heap);
1490-
add_clean_free(bcx, bx, heap);
1491-
let bcx = trans_into(bcx, contents, SaveIn(body));
1492-
revoke_clean(bcx, bx);
1493-
return immediate_rvalue_bcx(bcx, bx, box_ty);
1494-
}
1481+
fn trans_boxed_expr<'a>(
1482+
bcx: &'a Block<'a>,
1483+
box_ty: ty::t,
1484+
contents: &ast::Expr,
1485+
contents_ty: ty::t,
1486+
heap: heap)
1487+
-> DatumBlock<'a> {
1488+
let _icx = push_ctxt("trans_boxed_expr");
1489+
if heap == heap_exchange {
1490+
let llty = type_of::type_of(bcx.ccx(), contents_ty);
1491+
let size = llsize_of(bcx.ccx(), llty);
1492+
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
1493+
heap_exchange, size);
1494+
add_clean_free(bcx, val, heap_exchange);
1495+
let bcx = trans_into(bcx, contents, SaveIn(val));
1496+
revoke_clean(bcx, val);
1497+
return immediate_rvalue_bcx(bcx, val, box_ty);
1498+
} else {
1499+
let base::MallocResult {
1500+
bcx,
1501+
smart_ptr: bx,
1502+
body
1503+
} = base::malloc_general(bcx, contents_ty, heap);
1504+
add_clean_free(bcx, bx, heap);
1505+
let bcx = trans_into(bcx, contents, SaveIn(body));
1506+
revoke_clean(bcx, bx);
1507+
return immediate_rvalue_bcx(bcx, bx, box_ty);
14951508
}
14961509
}
14971510

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

1523+
pub fn trans_gc<'a>(
1524+
mut bcx: &'a Block<'a>,
1525+
expr: &ast::Expr,
1526+
contents: &ast::Expr,
1527+
dest: Dest)
1528+
-> &'a Block<'a> {
1529+
let contents_ty = expr_ty(bcx, contents);
1530+
let box_ty = ty::mk_box(bcx.tcx(), contents_ty);
1531+
let expr_ty = expr_ty(bcx, expr);
1532+
1533+
let addr = match dest {
1534+
Ignore => {
1535+
return trans_boxed_expr(bcx,
1536+
box_ty,
1537+
contents,
1538+
contents_ty,
1539+
heap_managed).bcx
1540+
}
1541+
SaveIn(addr) => addr,
1542+
};
1543+
1544+
let repr = adt::represent_type(bcx.ccx(), expr_ty);
1545+
adt::trans_start_init(bcx, repr, addr, 0);
1546+
let field_dest = adt::trans_field_ptr(bcx, repr, addr, 0, 0);
1547+
let contents_datum_block = trans_boxed_expr(bcx,
1548+
box_ty,
1549+
contents,
1550+
contents_ty,
1551+
heap_managed);
1552+
bcx = contents_datum_block.bcx;
1553+
bcx = contents_datum_block.datum.move_to(bcx, INIT, field_dest);
1554+
1555+
// Next, wrap it up in the struct.
1556+
bcx
1557+
}
1558+
15101559
// Important to get types for both lhs and rhs, because one might be _|_
15111560
// and the other not.
15121561
fn trans_eager_binop<'a>(

src/librustc/middle/trans/tvec.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use back::abi;
1313
use lib;
1414
use lib::llvm::{llvm, ValueRef};
1515
use middle::lang_items::StrDupUniqFnLangItem;
16-
use middle::trans::base;
1716
use middle::trans::base::*;
17+
use middle::trans::base;
1818
use middle::trans::build::*;
1919
use middle::trans::callee;
2020
use middle::trans::common::*;
@@ -23,14 +23,12 @@ use middle::trans::expr::{Dest, Ignore, SaveIn};
2323
use middle::trans::expr;
2424
use middle::trans::glue;
2525
use middle::trans::machine::{llsize_of, nonzero_llsize_of, llsize_of_alloc};
26+
use middle::trans::type_::Type;
2627
use middle::trans::type_of;
2728
use middle::ty;
2829
use util::common::indenter;
2930
use util::ppaux::ty_to_str;
3031

31-
use middle::trans::type_::Type;
32-
33-
use std::option::None;
3432
use syntax::ast;
3533
use syntax::codemap;
3634

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

src/librustc/middle/ty.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use driver::session;
1212
use metadata::csearch;
1313
use metadata;
1414
use middle::const_eval;
15+
use middle::lang_items::{ExchangeHeapLangItem, OpaqueStructLangItem};
1516
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
16-
use middle::lang_items::OpaqueStructLangItem;
1717
use middle::freevars;
1818
use middle::resolve;
1919
use middle::resolve_lifetime;
@@ -3241,6 +3241,20 @@ pub fn expr_kind(tcx: ctxt,
32413241
RvalueDatumExpr
32423242
}
32433243

3244+
ast::ExprBox(place, _) => {
3245+
// Special case `~T` for now:
3246+
let def_map = tcx.def_map.borrow();
3247+
let definition = match def_map.get().find(&place.id) {
3248+
Some(&def) => def,
3249+
None => fail!("no def for place"),
3250+
};
3251+
let def_id = ast_util::def_id_of_def(definition);
3252+
match tcx.lang_items.items[ExchangeHeapLangItem as uint] {
3253+
Some(item_def_id) if def_id == item_def_id => RvalueDatumExpr,
3254+
Some(_) | None => RvalueDpsExpr,
3255+
}
3256+
}
3257+
32443258
ast::ExprParen(e) => expr_kind(tcx, method_map, e),
32453259

32463260
ast::ExprMac(..) => {

src/librustc/middle/typeck/check/mod.rs

+70-1
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ type parameter).
7878

7979

8080
use middle::const_eval;
81+
use middle::lang_items::{ExchangeHeapLangItem, GcLangItem};
82+
use middle::lang_items::{ManagedHeapLangItem};
83+
use middle::lint::unreachable_code;
8184
use middle::pat_util::pat_id_map;
8285
use middle::pat_util;
83-
use middle::lint::unreachable_code;
8486
use middle::subst::Subst;
8587
use middle::ty::{FnSig, VariantInfo};
8688
use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
@@ -2679,6 +2681,73 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
26792681
fcx.write_ty(id, typ);
26802682
}
26812683

2684+
ast::ExprBox(place, subexpr) => {
2685+
check_expr(fcx, place);
2686+
check_expr(fcx, subexpr);
2687+
2688+
let mut checked = false;
2689+
match place.node {
2690+
ast::ExprPath(ref path) => {
2691+
// XXX(pcwalton): For now we hardcode the two permissible
2692+
// places: the exchange heap and the managed heap.
2693+
let definition = lookup_def(fcx, path.span, place.id);
2694+
let def_id = ast_util::def_id_of_def(definition);
2695+
match tcx.lang_items.items[ExchangeHeapLangItem as uint] {
2696+
Some(item_def_id) if def_id == item_def_id => {
2697+
fcx.write_ty(id, ty::mk_uniq(tcx, ty::mt {
2698+
ty: fcx.expr_ty(subexpr),
2699+
mutbl: ast::MutImmutable,
2700+
}));
2701+
checked = true
2702+
}
2703+
Some(_) | None => {}
2704+
}
2705+
if !checked {
2706+
match tcx.lang_items
2707+
.items[ManagedHeapLangItem as uint] {
2708+
Some(item_def_id) if def_id == item_def_id => {
2709+
// Assign the magic `Gc<T>` struct.
2710+
let gc_struct_id =
2711+
match tcx.lang_items
2712+
.require(GcLangItem) {
2713+
Ok(id) => id,
2714+
Err(msg) => {
2715+
tcx.sess.span_err(expr.span, msg);
2716+
ast::DefId {
2717+
crate: ast::CRATE_NODE_ID,
2718+
node: ast::DUMMY_NODE_ID,
2719+
}
2720+
}
2721+
};
2722+
let regions =
2723+
ty::NonerasedRegions(opt_vec::Empty);
2724+
let sty = ty::mk_struct(tcx,
2725+
gc_struct_id,
2726+
substs {
2727+
self_ty: None,
2728+
tps: ~[
2729+
fcx.expr_ty(
2730+
subexpr)
2731+
],
2732+
regions: regions,
2733+
});
2734+
fcx.write_ty(id, sty);
2735+
checked = true
2736+
}
2737+
Some(_) | None => {}
2738+
}
2739+
}
2740+
}
2741+
_ => {}
2742+
}
2743+
2744+
if !checked {
2745+
tcx.sess.span_err(expr.span,
2746+
"only the managed heap and exchange heap are \
2747+
currently supported")
2748+
}
2749+
}
2750+
26822751
ast::ExprLit(lit) => {
26832752
let typ = check_lit(fcx, lit);
26842753
fcx.write_ty(id, typ);

src/librustc/middle/typeck/check/regionck.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,7 @@ pub mod guarantor {
10481048
ast::ExprAddrOf(..) |
10491049
ast::ExprBinary(..) |
10501050
ast::ExprVstore(..) |
1051+
ast::ExprBox(..) |
10511052
ast::ExprBreak(..) |
10521053
ast::ExprAgain(..) |
10531054
ast::ExprRet(..) |

0 commit comments

Comments
 (0)