Skip to content

librustc: Implement placement box for GC and unique pointers. #11055

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

Merged
merged 1 commit into from
Jan 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -721,6 +721,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 @@ -2616,6 +2616,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