diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index d5823e025be..0beae3ce5c1 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -394,6 +394,10 @@ fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex { 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, _) | diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index c50190f0b68..e79d1649099 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -720,6 +720,11 @@ fn walk_expr(&mut self, 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); diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index f95fec4c9df..a89a9eb7502 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -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; @@ -256,5 +256,9 @@ pub fn collect_language_items(crate: &ast::Crate, 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; } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 8ffb78f8ac4..15d499962a1 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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); } } @@ -1252,7 +1252,8 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode) } ExprIndex(_, l, r) | - ExprBinary(_, _, l, r) => { + ExprBinary(_, _, l, r) | + ExprBox(l, r) => { self.propagate_through_exprs([l, r], succ) } @@ -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") diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 645c2e79a56..14eb5643147 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -438,7 +438,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt { 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); } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index fa83726a464..02c7a416320 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -591,6 +591,11 @@ fn has_dtor(tcx: ty::ctxt, ty: ty::t) -> bool { 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, diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 3197084f73c..11804369a58 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2613,6 +2613,11 @@ fn walk_expr(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 => () diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 970e3e4eac7..06a85d70284 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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); } @@ -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` 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, @@ -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); } } @@ -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>( diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 5b8d2a0f6b5..da7f3068fb9 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -13,8 +13,8 @@ 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::*; @@ -23,14 +23,12 @@ 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; @@ -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); } + diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a202b810b75..05b59baa49c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -12,8 +12,8 @@ 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; @@ -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(..) => { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a1e360dae8c..c06fcdba369 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -78,9 +78,11 @@ 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}; @@ -2679,6 +2681,73 @@ fn check_struct_enum_variant(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` 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); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 668163881a9..7938bf3ffe2 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -1048,6 +1048,7 @@ fn guarantor(rcx: &mut Rcx, expr: &ast::Expr) -> Option { ast::ExprAddrOf(..) | ast::ExprBinary(..) | ast::ExprVstore(..) | + ast::ExprBox(..) | ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprRet(..) | diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 1b53c70a9a1..4cbecc9b42f 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -21,6 +21,14 @@ use managed; /// Immutable garbage-collected pointer type +#[lang="gc"] +#[cfg(not(test))] +#[no_send] +pub struct Gc { + priv ptr: @T +} + +#[cfg(test)] #[no_send] pub struct Gc { priv ptr: @T @@ -54,6 +62,16 @@ fn clone(&self) -> Gc { } } +/// An value that represents the task-local managed heap. +/// +/// Use this like `let foo = box(GC) Bar::new(...);` +#[lang="managed_heap"] +#[cfg(not(test))] +pub static GC: () = (); + +#[cfg(test)] +pub static GC: () = (); + /// The `Send` bound restricts this to acyclic graphs where it is well-defined. /// /// A `Freeze` bound would also work, but `Send` *or* `Freeze` cannot be expressed. diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs index 424c4fd6b2f..dc8ea34c84b 100644 --- a/src/libstd/owned.rs +++ b/src/libstd/owned.rs @@ -12,6 +12,20 @@ #[cfg(not(test))] use cmp::*; +/// A value that represents the global exchange heap. This is the default +/// place that the `box` keyword allocates into when no place is supplied. +/// +/// The following two examples are equivalent: +/// +/// let foo = box(HEAP) Bar::new(...); +/// let foo = box Bar::new(...); +#[lang="exchange_heap"] +#[cfg(not(test))] +pub static HEAP: () = (); + +#[cfg(test)] +pub static HEAP: () = (); + #[cfg(not(test))] impl Eq for ~T { #[inline] diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index afacc4e8c17..36bcc81c06d 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -86,6 +86,10 @@ pub use comm::{Port, Chan, SharedChan}; pub use task::spawn; +// Reexported statics +#[cfg(not(test))] +pub use gc::GC; + /// Disposes of a value. #[inline] pub fn drop(_x: T) { } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2458577aa86..ef348e52f6e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -547,6 +547,8 @@ pub enum CallSugar { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum Expr_ { ExprVstore(@Expr, ExprVstore), + // First expr is the place; second expr is the value. + ExprBox(@Expr, @Expr), ExprVec(~[@Expr], Mutability), ExprCall(@Expr, ~[@Expr], CallSugar), ExprMethodCall(NodeId, @Expr, Ident, ~[P], ~[@Expr], CallSugar), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c73edb0bfcf..409368ce3df 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -714,6 +714,9 @@ pub fn noop_fold_expr(e: @Expr, folder: &mut T) -> @Expr { ExprVstore(e, v) => { ExprVstore(folder.fold_expr(e), v) } + ExprBox(p, e) => { + ExprBox(folder.fold_expr(p), folder.fold_expr(e)) + } ExprVec(ref exprs, mutt) => { ExprVec(exprs.map(|&x| folder.fold_expr(x)), mutt) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 149b7c1cf18..0424c71dd59 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -23,7 +23,7 @@ use ast::{Crate, CrateConfig, Decl, DeclItem}; use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf}; use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; -use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock}; +use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody}; use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex}; use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac}; @@ -2321,6 +2321,20 @@ pub fn parse_prefix_expr(&mut self) -> @Expr { token::IDENT(_, _) if self.is_keyword(keywords::Box) => { self.bump(); + // Check for a place: `box(PLACE) EXPR`. + if self.eat(&token::LPAREN) { + // Support `box() EXPR` as the default. + if !self.eat(&token::RPAREN) { + let place = self.parse_expr(); + self.expect(&token::RPAREN); + let subexpression = self.parse_prefix_expr(); + hi = subexpression.span.hi; + ex = ExprBox(place, subexpression); + return self.mk_expr(lo, hi, ex); + } + } + + // Otherwise, we use the unique pointer default. let subexpression = self.parse_prefix_expr(); hi = subexpression.span.hi; // HACK: turn `box [...]` into a boxed-evec diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1e2e5dbc010..ea9f0907b7a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1148,6 +1148,13 @@ fn print_field(s: &mut State, field: &ast::Field) { print_expr_vstore(s, v); print_expr(s, e); }, + ast::ExprBox(p, e) => { + word(&mut s.s, "box"); + word(&mut s.s, "("); + print_expr(s, p); + word_space(s, ")"); + print_expr(s, e); + } ast::ExprVec(ref exprs, mutbl) => { ibox(s, indent_unit); word(&mut s.s, "["); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 8e678a9bb73..1f0572a7785 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -614,6 +614,10 @@ pub fn walk_expr>(visitor: &mut V, expression: &Expr, en ExprVstore(subexpression, _) => { visitor.visit_expr(subexpression, env.clone()) } + ExprBox(place, subexpression) => { + visitor.visit_expr(place, env.clone()); + visitor.visit_expr(subexpression, env.clone()) + } ExprVec(ref subexpressions, _) => { walk_exprs(visitor, *subexpressions, env.clone()) } diff --git a/src/test/compile-fail/new-box-syntax-bad.rs b/src/test/compile-fail/new-box-syntax-bad.rs new file mode 100644 index 00000000000..942c8621207 --- /dev/null +++ b/src/test/compile-fail/new-box-syntax-bad.rs @@ -0,0 +1,14 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that the new `box` syntax works with unique pointers and GC pointers. + +use std::gc::Gc; +use std::owned::HEAP; + +pub fn main() { + let x: Gc = box(HEAP) 2; //~ ERROR mismatched types + let y: Gc = box(HEAP)(1 + 2); //~ ERROR mismatched types + let z: ~int = box(GC)(4 + 5); //~ ERROR mismatched types +} + diff --git a/src/test/run-pass/new-box-syntax.rs b/src/test/run-pass/new-box-syntax.rs index 2d6e7a4ef0a..d237c4d9a4e 100644 --- a/src/test/run-pass/new-box-syntax.rs +++ b/src/test/run-pass/new-box-syntax.rs @@ -1,8 +1,26 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -pub fn main() { - let x: ~int = box 3; - println!("{}", *x); +// Tests that the new `box` syntax works with unique pointers and GC pointers. + +use std::gc::Gc; +use std::owned::HEAP; + +struct Structure { + x: int, + y: int, +} + +pub fn main() { + let x: ~int = box(HEAP) 2; + let y: ~int = box 2; + let z: Gc = box(GC) 2; + let a: Gc = box(GC) Structure { + x: 10, + y: 20, + }; + let b: ~int = box()(1 + 2); + let c = box()(3 + 4); + let d = box(GC)(5 + 6); }