From 31c5cec55bd8b43e6082f79dff888f52b585621d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 2 Aug 2012 16:00:45 -0700 Subject: [PATCH] Purge placement new; Make borrowck know about unary move. cc #3071 --- src/libcore/pipes.rs | 4 +- src/libstd/arena.rs | 17 +++-- src/libsyntax/ast.rs | 6 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/fold.rs | 5 -- src/libsyntax/parse/parser.rs | 9 +-- src/libsyntax/print/pprust.rs | 7 -- src/libsyntax/visit.rs | 4 -- src/rustc/middle/astencode.rs | 2 +- src/rustc/middle/borrowck/categorization.rs | 11 ++- src/rustc/middle/borrowck/check_loans.rs | 3 + src/rustc/middle/liveness.rs | 5 +- src/rustc/middle/resolve3.rs | 12 ++-- src/rustc/middle/trans/base.rs | 39 +---------- src/rustc/middle/trans/type_use.rs | 3 - src/rustc/middle/tstate/auxiliary.rs | 4 +- src/rustc/middle/typeck/check.rs | 49 +------------ src/rustc/middle/typeck/check/regionmanip.rs | 69 ------------------- src/rustc/middle/typeck/check/writeback.rs | 4 -- src/test/bench/shootout-binarytrees.rs | 9 +-- .../compile-fail/borrowck-unary-move-2.rs | 9 +++ src/test/compile-fail/borrowck-unary-move.rs | 11 +++ .../placement-new-bad-method-type.rs | 19 ----- src/test/run-pass/placement-new-arena.rs | 2 +- src/test/run-pass/placement-new-leaky.rs | 27 -------- src/test/run-pass/regions-mock-trans-impls.rs | 29 ++------ 26 files changed, 75 insertions(+), 286 deletions(-) create mode 100644 src/test/compile-fail/borrowck-unary-move-2.rs create mode 100644 src/test/compile-fail/borrowck-unary-move.rs delete mode 100644 src/test/compile-fail/placement-new-bad-method-type.rs delete mode 100644 src/test/run-pass/placement-new-leaky.rs diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index fd42ad73d3d..c1f39a9470c 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -887,7 +887,7 @@ fn try_recv() -> option { while result == none && ports.len() > 0 { let i = wait_many(ports.map(|p| p.header())); alt move ports[i].try_recv() { - some(m) { + some(copy m) { result = some(move m); } none { @@ -907,7 +907,7 @@ fn try_recv() -> option { fn recv() -> T { match move self.try_recv() { - some(x) { move x } + some(copy x) { move x } none { fail ~"port_set: endpoints closed" } } } diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index b9bc977db31..84675d9569a 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -4,6 +4,7 @@ import list; import list::{list, cons, nil}; +import unsafe::reinterpret_cast; type chunk = {data: ~[u8], mut fill: uint}; @@ -27,7 +28,12 @@ fn arena() -> arena { arena_with_size(32u) } -impl arena for arena { +#[abi = "rust-intrinsic"] +extern mod rusti { + fn move_val_init(&dst: T, -src: T); +} + +impl &arena { fn alloc_grow(n_bytes: uint, align: uint) -> *() { // Allocate a new chunk. let mut head = list::head(self.chunks); @@ -59,10 +65,13 @@ fn alloc_inner(n_bytes: uint, align: uint) -> *() { } #[inline(always)] - fn alloc(tydesc: *()) -> *() { + fn alloc(op: fn() -> T) -> &self/T { unsafe { - let tydesc = tydesc as *sys::type_desc; - self.alloc_inner((*tydesc).size, (*tydesc).align) + let tydesc = sys::get_type_desc::(); + let ptr = self.alloc_inner((*tydesc).size, (*tydesc).align); + let ptr: *mut T = reinterpret_cast(ptr); + rusti::move_val_init(*ptr, op()); + return reinterpret_cast(ptr); } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5f62c2901f0..36ac307ea5c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -81,7 +81,7 @@ enum def { def_ty(def_id), def_prim_ty(prim_ty), def_ty_param(def_id, uint), - def_binding(node_id), + def_binding(node_id, binding_mode), def_use(def_id), def_upvar(node_id /* local id of closed over var */, @def /* closed over def */, @@ -342,10 +342,6 @@ enum expr_ { expr_ret(option<@expr>), expr_log(int, @expr, @expr), - expr_new(/* arena */ @expr, - /* id for the alloc() call */ node_id, - /* value */ @expr), - /* just an assert */ expr_assert(@expr), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 58650e147cc..d1c553ec5ae 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -55,7 +55,7 @@ fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} { def_variant(_, id) | def_ty(id) | def_ty_param(id, _) | def_use(id) | def_class(id, _) { id } def_arg(id, _) | def_local(id, _) | def_self(id) | - def_upvar(id, _, _) | def_binding(id) | def_region(id) + def_upvar(id, _, _) | def_binding(id, _) | def_region(id) | def_typaram_binder(id) { local_def(id) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ee0512e1b07..bbf6df468f8 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -395,11 +395,6 @@ fn fold_field_(field: field, fld: ast_fold) -> field { let fold_mac = |x| fold_mac_(x, fld); return alt e { - expr_new(p, i, v) { - expr_new(fld.fold_expr(p), - fld.new_id(i), - fld.fold_expr(v)) - } expr_vstore(e, v) { expr_vstore(fld.fold_expr(e), v) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 537e72f707f..f697685796f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,7 +27,7 @@ expr_call, expr_cast, expr_copy, expr_do_body, expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index, expr_lit, expr_log, expr_loop, - expr_loop_body, expr_mac, expr_move, expr_new, expr_path, + expr_loop_body, expr_mac, expr_move, expr_path, expr_rec, expr_ret, expr_swap, expr_struct, expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore, expr_while, extern_fn, field, fn_decl, foreign_item, foreign_item_fn, foreign_mod, @@ -783,13 +783,6 @@ fn parse_bottom_expr() -> pexpr { } } else if token::is_bar(self.token) { return pexpr(self.parse_lambda_expr()); - } else if self.eat_keyword(~"new") { - self.expect(token::LPAREN); - let r = self.parse_expr(); - self.expect(token::RPAREN); - let v = self.parse_expr(); - return self.mk_pexpr(lo, self.span.hi, - expr_new(r, self.get_id(), v)); } else if self.eat_keyword(~"if") { return pexpr(self.parse_if_expr()); } else if self.eat_keyword(~"for") { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 02a888e4022..800800504fd 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1190,13 +1190,6 @@ fn print_field(s: ps, field: ast::field) { word_nbsp(s, ~"assert"); print_expr(s, expr); } - ast::expr_new(p, _, v) { - word_nbsp(s, ~"new"); - popen(s); - print_expr(s, p); - pclose(s); - print_expr(s, v); - } ast::expr_mac(m) { print_mac(s, m); } } s.ann.post(ann_node); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4cbe13b6d5c..f2159af34e7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -361,10 +361,6 @@ fn visit_mac(m: mac, e: E, v: vt) { fn visit_expr(ex: @expr, e: E, v: vt) { alt ex.node { - expr_new(pool, _, val) { - v.visit_expr(pool, e, v); - v.visit_expr(val, e, v); - } expr_vstore(x, _) { v.visit_expr(x, e, v); } expr_vec(es, _) { visit_exprs(es, e, v); } expr_rec(flds, base) { diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 8f672d19047..5478f8fb423 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -366,7 +366,7 @@ fn tr(xcx: extended_decode_ctxt) -> ast::def { ast::def_ty(did) { ast::def_ty(did.tr(xcx)) } ast::def_prim_ty(p) { ast::def_prim_ty(p) } ast::def_ty_param(did, v) { ast::def_ty_param(did.tr(xcx), v) } - ast::def_binding(nid) { ast::def_binding(xcx.tr_id(nid)) } + ast::def_binding(nid, bm) { ast::def_binding(xcx.tr_id(nid), bm) } ast::def_use(did) { ast::def_use(did.tr(xcx)) } ast::def_upvar(nid1, def, nid2) { ast::def_upvar(xcx.tr_id(nid1), @(*def).tr(xcx), xcx.tr_id(nid2)) diff --git a/src/rustc/middle/borrowck/categorization.rs b/src/rustc/middle/borrowck/categorization.rs index ebcb380b4e9..977d373c3f9 100644 --- a/src/rustc/middle/borrowck/categorization.rs +++ b/src/rustc/middle/borrowck/categorization.rs @@ -178,7 +178,7 @@ fn cat_expr(expr: @ast::expr) -> cmt { ast::expr_copy(*) | ast::expr_cast(*) | ast::expr_fail(*) | ast::expr_vstore(*) | ast::expr_vec(*) | ast::expr_tup(*) | ast::expr_if(*) | ast::expr_log(*) | - ast::expr_new(*) | ast::expr_binary(*) | ast::expr_while(*) | + ast::expr_binary(*) | ast::expr_while(*) | ast::expr_block(*) | ast::expr_loop(*) | ast::expr_alt(*) | ast::expr_lit(*) | ast::expr_break | ast::expr_mac(*) | ast::expr_again | ast::expr_rec(*) | ast::expr_struct(*) | @@ -266,7 +266,14 @@ fn cat_def(id: ast::node_id, mutbl:m, ty:expr_ty} } - ast::def_binding(pid) { + ast::def_binding(vid, ast::bind_by_value) { + // by-value bindings are basically local variables + @{id:id, span:span, + cat:cat_local(vid), lp:some(@lp_local(vid)), + mutbl:m_imm, ty:expr_ty} + } + + ast::def_binding(pid, ast::bind_by_ref) { // bindings are "special" since they are implicit pointers. // lookup the mutability for this binding that we found in diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index 79c562ae5b8..4fa149b931b 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -579,6 +579,9 @@ fn check_loans_in_expr(expr: @ast::expr, self.check_assignment(at_straight_up, dest); self.check_move_out(src); } + ast::expr_unary_move(src) { + self.check_move_out(src); + } ast::expr_assign(dest, _) | ast::expr_assign_op(_, dest, _) { self.check_assignment(at_straight_up, dest); diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index 7f18dae0db4..a868c9190f8 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -465,7 +465,7 @@ fn visit_expr(expr: @expr, &&self: @ir_maps, vt: vt<@ir_maps>) { // otherwise, live nodes are not required: expr_index(*) | expr_field(*) | expr_vstore(*) | expr_vec(*) | expr_rec(*) | expr_call(*) | expr_tup(*) | - expr_new(*) | expr_log(*) | expr_binary(*) | + expr_log(*) | expr_binary(*) | expr_assert(*) | expr_addr_of(*) | expr_copy(*) | expr_loop_body(*) | expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_fail(*) | @@ -1094,7 +1094,6 @@ fn propagate_through_expr(expr: @expr, succ: live_node) -> live_node { self.propagate_through_expr(l, ln) } - expr_new(l, _, r) | expr_log(_, l, r) | expr_index(l, r) | expr_binary(_, l, r) { @@ -1463,7 +1462,7 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) { expr_while(*) | expr_loop(*) | expr_index(*) | expr_field(*) | expr_vstore(*) | expr_vec(*) | expr_rec(*) | expr_tup(*) | - expr_new(*) | expr_log(*) | expr_binary(*) | + expr_log(*) | expr_binary(*) | expr_assert(*) | expr_copy(*) | expr_loop_body(*) | expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_fail(*) | diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index 2b240271024..243c2af19b2 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -15,11 +15,11 @@ def_typaram_binder}; import syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op}; import syntax::ast::{expr_binary, expr_cast, expr_field, expr_fn}; -import syntax::ast::{expr_fn_block, expr_index, expr_new, expr_path}; +import syntax::ast::{expr_fn_block, expr_index, expr_path}; import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param}; import syntax::ast::{def_upvar, def_use, def_variant, div, eq, expr}; import syntax::ast::{expr_assign_op, expr_binary, expr_cast, expr_field}; -import syntax::ast::{expr_fn, expr_fn_block, expr_index, expr_new, expr_path}; +import syntax::ast::{expr_fn, expr_fn_block, expr_index, expr_path}; import syntax::ast::{expr_struct, expr_unary, fn_decl, foreign_item}; import syntax::ast::{foreign_item_fn, ge, gt, ident, trait_ref, impure_fn}; import syntax::ast::{instance_var, item, item_class, item_const, item_enum}; @@ -3734,7 +3734,7 @@ fn resolve_pattern(pattern: @pat, let pat_id = pattern.id; do walk_pat(pattern) |pattern| { alt pattern.node { - pat_ident(_, path, _) + pat_ident(binding_mode, path, _) if !path.global && path.idents.len() == 1u => { // The meaning of pat_ident with no type parameters @@ -3781,7 +3781,7 @@ enum variant", // For pattern arms, we must use // `def_binding` definitions. - def_binding(pattern.id) + def_binding(pattern.id, binding_mode) } IrrefutableMode { // But for locals, we use `def_local`. @@ -4315,10 +4315,6 @@ fn record_impls_for_expr_if_necessary(expr: @expr) { self.impl_map.insert(expr.id, self.current_module.impl_scopes); } - expr_new(container, _, _) { - self.impl_map.insert(container.id, - self.current_module.impl_scopes); - } _ { // Nothing to do. } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 203d17ec1a9..78c24cdfdbf 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2411,7 +2411,7 @@ fn take_local(table: hashmap, assert (cx.fcx.llargs.contains_key(nid)); return take_local(cx.fcx.llargs, nid); } - ast::def_local(nid, _) | ast::def_binding(nid) { + ast::def_local(nid, _) | ast::def_binding(nid, _) { assert (cx.fcx.lllocals.contains_key(nid)); return take_local(cx.fcx.lllocals, nid); } @@ -3771,43 +3771,6 @@ fn unrooted(bcx: block, e: @ast::expr, dest: dest) -> block { assert dest == ignore; return trans_assign_op(bcx, e, op, dst, src); } - ast::expr_new(pool, alloc_id, val) { - // First, call pool->alloc(tydesc) to get back a void*. - // Then, cast this memory to the required type and evaluate value - // into it. - let ccx = bcx.ccx(); - - // Allocate space for the ptr that will be returned from - // `pool.alloc()`: - let ptr_ty = expr_ty(bcx, e); - let ptr_ptr_val = alloc_ty(bcx, ptr_ty); - - debug!{"ptr_ty = %s", ppaux::ty_to_str(tcx, ptr_ty)}; - debug!{"ptr_ptr_val = %s", val_str(ccx.tn, ptr_ptr_val)}; - - let void_ty = ty::mk_nil_ptr(tcx); - let llvoid_ty = type_of(ccx, void_ty); - let voidval = PointerCast(bcx, ptr_ptr_val, T_ptr(llvoid_ty)); - debug!{"voidval = %s", val_str(ccx.tn, voidval)}; - - let static_ti = get_tydesc(ccx, expr_ty(bcx, val)); - lazily_emit_all_tydesc_glue(ccx, static_ti); - let lltydesc = PointerCast(bcx, static_ti.tydesc, llvoid_ty); - - let origin = bcx.ccx().maps.method_map.get(alloc_id); - let bcx = trans_call_inner( - bcx, e.info(), node_id_type(bcx, alloc_id), void_ty, - |bcx| impl::trans_method_callee(bcx, alloc_id, - pool, origin), - arg_vals(~[lltydesc]), - save_in(voidval)); - - debug!{"dest = %s", dest_str(ccx, dest)}; - let ptr_val = Load(bcx, ptr_ptr_val); - debug!{"ptr_val = %s", val_str(ccx.tn, ptr_val)}; - let bcx = trans_expr(bcx, val, save_in(ptr_val)); - store_in_dest(bcx, ptr_val, dest) - } _ { bcx.tcx().sess.span_bug(e.span, ~"trans_expr reached \ fall-through case"); diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 486ea2da835..c5a35b4b587 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -228,9 +228,6 @@ fn mark_for_expr(cx: ctx, e: @expr) { expr_log(_, _, val) { node_type_needs(cx, use_tydesc, val.id); } - expr_new(_, _, v) { - node_type_needs(cx, use_repr, v.id); - } expr_call(f, _, _) { vec::iter(ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, f.id)), |a| { alt a.mode { diff --git a/src/rustc/middle/tstate/auxiliary.rs b/src/rustc/middle/tstate/auxiliary.rs index aa249fc3604..eb39d4ec561 100644 --- a/src/rustc/middle/tstate/auxiliary.rs +++ b/src/rustc/middle/tstate/auxiliary.rs @@ -525,7 +525,7 @@ fn expr_to_constr_arg(tcx: ty::ctxt, e: @expr) -> @constr_arg_use { expr_path(p) { alt tcx.def_map.find(e.id) { some(def_local(nid, _)) | some(def_arg(nid, _)) | - some(def_binding(nid)) | some(def_upvar(nid, _, _)) { + some(def_binding(nid, _)) | some(def_upvar(nid, _, _)) { return @respan(p.span, carg_ident({ident: p.idents[0], node: nid})); } @@ -762,7 +762,7 @@ fn local_node_id_to_def(fcx: fn_ctxt, i: node_id) -> option { fn local_node_id_to_def_id(fcx: fn_ctxt, i: node_id) -> option { alt local_node_id_to_def(fcx, i) { some(def_local(nid, _)) | some(def_arg(nid, _)) | - some(def_binding(nid)) | some(def_upvar(nid, _, _)) { + some(def_binding(nid, _)) | some(def_upvar(nid, _, _)) { some(local_def(nid)) } _ { none } diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index c6856d10dc5..35b2560f00c 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -70,7 +70,7 @@ import astconv::{ast_region_to_region}; import collect::{methods}; // ccx.to_ty() import middle::ty::{tv_vid, vid}; -import regionmanip::{replace_bound_regions_in_fn_ty, region_of}; +import regionmanip::{replace_bound_regions_in_fn_ty}; import rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope}; import rscope::{in_binding_rscope, region_scope, type_rscope}; import syntax::ast::ty_i; @@ -1846,51 +1846,6 @@ fn get_node(f: spanned) -> field { f.node } } } } - ast::expr_new(p, alloc_id, v) { - bot |= check_expr(fcx, p, none); - bot |= check_expr(fcx, v, none); - - let p_ty = fcx.expr_ty(p); - - let lkup = method::lookup(fcx, p, p, expr.id, alloc_id, - @~"alloc", p_ty, ~[], false); - alt lkup.method() { - some(entry) { - fcx.ccx.method_map.insert(alloc_id, entry); - - // Check that the alloc() method has the expected - // type, which should be fn(tydesc: *()) -> *(). - let expected_ty = { - let ty_nilp = ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), - mutbl: ast::m_imm}); - let m = ast::expl(ty::default_arg_mode_for_ty(ty_nilp)); - ty::mk_fn(tcx, {purity: ast::impure_fn, - proto: ast::proto_any, - inputs: ~[{mode: m, ty: ty_nilp}], - output: ty_nilp, - ret_style: ast::return_val}) - }; - - demand::suptype(fcx, expr.span, - expected_ty, fcx.node_ty(alloc_id)); - } - - none { - let t_err = fcx.infcx.resolve_type_vars_if_possible(p_ty); - let msg = fmt!{"no `alloc()` method found for type `%s`", - fcx.infcx.ty_to_str(t_err)}; - tcx.sess.span_err(expr.span, msg); - } - } - - // The region value must have a type like &r.T. The resulting - // memory will be allocated into the region `r`. - let pool_region = region_of(fcx, p); - let v_ty = fcx.expr_ty(v); - let res_ty = ty::mk_rptr(tcx, pool_region, {ty: v_ty, - mutbl: ast::m_imm}); - fcx.write_ty(expr.id, res_ty); - } } if bot { fcx.write_bot(expr.id); } @@ -2204,7 +2159,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> ast::def_variant(_, id) | ast::def_class(id, _) { return ty::lookup_item_type(fcx.ccx.tcx, id); } - ast::def_binding(nid) { + ast::def_binding(nid, _) { assert (fcx.locals.contains_key(nid)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, nid)); return no_params(typ); diff --git a/src/rustc/middle/typeck/check/regionmanip.rs b/src/rustc/middle/typeck/check/regionmanip.rs index a2bfc9c3ffa..e50ec14ccf9 100644 --- a/src/rustc/middle/typeck/check/regionmanip.rs +++ b/src/rustc/middle/typeck/check/regionmanip.rs @@ -161,72 +161,3 @@ fn replace_bound_regions( } } } - -/* Returns the region that &expr should be placed into. If expr is an - * lvalue, this will be the region of the lvalue. Otherwise, if region is - * an rvalue, the semantics are that the result is stored into a temporary - * stack position and so the resulting region will be the enclosing block. - */ -fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { - debug!{"region_of(expr=%s)", expr_to_str(expr)}; - return alt expr.node { - ast::expr_path(path) { - def(fcx, expr, lookup_def(fcx, path.span, expr.id))} - ast::expr_field(base, _, _) { - deref(fcx, base)} - ast::expr_index(base, _) { - deref(fcx, base)} - ast::expr_unary(ast::deref, base) { - deref(fcx, base)} - _ { - borrow(fcx, expr)} - }; - - fn borrow(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { - ty::encl_region(fcx.ccx.tcx, expr.id) - } - - fn deref(fcx: @fn_ctxt, base: @ast::expr) -> ty::region { - let base_ty = fcx.expr_ty(base); - let base_ty = structurally_resolved_type(fcx, base.span, base_ty); - alt ty::get(base_ty).struct { - ty::ty_rptr(region, _) { region } - ty::ty_box(_) | ty::ty_uniq(_) { borrow(fcx, base) } - _ { region_of(fcx, base) } - } - } - - fn def(fcx: @fn_ctxt, expr: @ast::expr, d: ast::def) -> ty::region { - alt d { - ast::def_arg(local_id, _) | - ast::def_local(local_id, _) | - ast::def_binding(local_id) { - debug!{"region_of.def/arg/local/binding(id=%d)", local_id}; - let local_scope = fcx.ccx.tcx.region_map.get(local_id); - ty::re_scope(local_scope) - } - ast::def_upvar(_, inner, _) { - debug!{"region_of.def/upvar"}; - def(fcx, expr, *inner) - } - ast::def_self(*) { - alt fcx.in_scope_regions.find(ty::br_self) { - some(r) {r} - none { - // eventually, this should never happen... self should - // always be an &self.T rptr - borrow(fcx, expr) - } - } - } - ast::def_fn(_, _) | ast::def_mod(_) | - ast::def_foreign_mod(_) | ast::def_const(_) | - ast::def_use(_) | ast::def_variant(_, _) | - ast::def_ty(_) | ast::def_prim_ty(_) | - ast::def_ty_param(_, _) | ast::def_typaram_binder(*) | - ast::def_class(_, _) | ast::def_region(_) { - ty::re_static - } - } - } -} diff --git a/src/rustc/middle/typeck/check/writeback.rs b/src/rustc/middle/typeck/check/writeback.rs index 726cc2a7c70..84d05a8aee2 100644 --- a/src/rustc/middle/typeck/check/writeback.rs +++ b/src/rustc/middle/typeck/check/writeback.rs @@ -99,10 +99,6 @@ fn visit_expr(e: @ast::expr, wbcx: wb_ctxt, v: wb_vt) { } } - ast::expr_new(_, alloc_id, _) { - resolve_type_vars_for_node(wbcx, e.span, alloc_id); - } - ast::expr_binary(*) | ast::expr_unary(*) | ast::expr_assign_op(*) | ast::expr_index(*) { maybe_resolve_type_vars_for_node(wbcx, e.span, e.callee_id); diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index aadf8929015..8ccb2e61d41 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -15,11 +15,12 @@ fn item_check(t: &tree) -> int { fn bottom_up_tree(arena: &arena::arena, item: int, depth: int) -> &tree { if depth > 0 { - return new(*arena) node(bottom_up_tree(arena, 2 * item - 1, depth - 1), - bottom_up_tree(arena, 2 * item, depth - 1), - item); + return arena.alloc( + || node(bottom_up_tree(arena, 2 * item - 1, depth - 1), + bottom_up_tree(arena, 2 * item, depth - 1), + item)); } - return new(*arena) nil; + return arena.alloc(|| nil); } fn main(args: ~[~str]) { diff --git a/src/test/compile-fail/borrowck-unary-move-2.rs b/src/test/compile-fail/borrowck-unary-move-2.rs new file mode 100644 index 00000000000..53bb3a6d065 --- /dev/null +++ b/src/test/compile-fail/borrowck-unary-move-2.rs @@ -0,0 +1,9 @@ +class noncopyable { + i: (); new() { self.i = (); } drop { #error["dropped"]; } +} +enum wrapper = noncopyable; + +fn main() { + let x1 = wrapper(noncopyable()); + let _x2 = move *x1; //~ ERROR moving out of enum content +} \ No newline at end of file diff --git a/src/test/compile-fail/borrowck-unary-move.rs b/src/test/compile-fail/borrowck-unary-move.rs new file mode 100644 index 00000000000..1c8117fd820 --- /dev/null +++ b/src/test/compile-fail/borrowck-unary-move.rs @@ -0,0 +1,11 @@ +fn foo(+x: ~int) -> int { + let y = &*x; //~ NOTE loan of argument granted here + free(move x); //~ ERROR moving out of argument prohibited due to outstanding loan + *y +} + +fn free(+_x: ~int) { +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/placement-new-bad-method-type.rs b/src/test/compile-fail/placement-new-bad-method-type.rs deleted file mode 100644 index 2cbf91c8d2a..00000000000 --- a/src/test/compile-fail/placement-new-bad-method-type.rs +++ /dev/null @@ -1,19 +0,0 @@ -import libc, unsafe; - -enum malloc_pool = (); - -trait alloc { - fn alloc(sz: int, align: int) -> *(); -} - -impl methods of alloc for malloc_pool { - fn alloc(sz: int, align: int) -> *() { - fail; - } -} - -fn main() { - let p = &malloc_pool(()); - let x = new(*p) 4u; - //~^ ERROR mismatched types: expected `fn(*()) -> *()` -} diff --git a/src/test/run-pass/placement-new-arena.rs b/src/test/run-pass/placement-new-arena.rs index e3750c15417..60c70bfec30 100644 --- a/src/test/run-pass/placement-new-arena.rs +++ b/src/test/run-pass/placement-new-arena.rs @@ -3,7 +3,7 @@ fn main() { let p = &arena(); - let x = new(*p) 4u; + let x = p.alloc(|| 4u); io::print(fmt!{"%u", *x}); assert *x == 4u; } diff --git a/src/test/run-pass/placement-new-leaky.rs b/src/test/run-pass/placement-new-leaky.rs deleted file mode 100644 index 96e56a7d8e5..00000000000 --- a/src/test/run-pass/placement-new-leaky.rs +++ /dev/null @@ -1,27 +0,0 @@ -import libc, unsafe; - -enum malloc_pool = (); - -impl methods for malloc_pool { - fn alloc_inner(sz: uint, align: uint) -> *() { - unsafe { - unsafe::reinterpret_cast(libc::malloc(sz as libc::size_t)) - } - } - fn alloc(tydesc: *()) -> *() { - unsafe { - let tydesc = tydesc as *sys::type_desc; - self.alloc_inner((*tydesc).size, (*tydesc).align) - } - } -} - -fn main() { - let p = &malloc_pool(()); - let x = new(*p) 4u; - io::print(fmt!{"%u", *x}); - assert *x == 4u; - unsafe { - libc::free(unsafe::reinterpret_cast(x)); - } -} diff --git a/src/test/run-pass/regions-mock-trans-impls.rs b/src/test/run-pass/regions-mock-trans-impls.rs index 6b7848c267c..9cc4e2abca9 100644 --- a/src/test/run-pass/regions-mock-trans-impls.rs +++ b/src/test/run-pass/regions-mock-trans-impls.rs @@ -1,6 +1,6 @@ +use std; import libc, sys, unsafe; - -enum arena = (); +import std::arena::arena; type bcx = { fcx: &fcx @@ -15,34 +15,19 @@ x: int }; -impl arena for arena { - fn alloc_inner(sz: uint, _align: uint) -> *() unsafe { - return unsafe::reinterpret_cast(libc::malloc(sz as libc::size_t)); - } - fn alloc(tydesc: *()) -> *() { - unsafe { - let tydesc = tydesc as *sys::type_desc; - self.alloc_inner((*tydesc).size, (*tydesc).align) - } - } -} - fn h(bcx : &bcx) -> &bcx { - return new(*bcx.fcx.arena) { fcx: bcx.fcx }; + return bcx.fcx.arena.alloc(|| { fcx: bcx.fcx }); } fn g(fcx : &fcx) { let bcx = { fcx: fcx }; - let bcx2 = h(&bcx); - unsafe { - libc::free(unsafe::reinterpret_cast(bcx2)); - } + h(&bcx); } fn f(ccx : &ccx) { - let a = arena(()); - let fcx = { arena: &a, ccx: ccx }; - return g(&fcx); + let a = arena(); + let fcx = &{ arena: &a, ccx: ccx }; + return g(fcx); } fn main() { -- GitLab