parent
c2bb2f0837
commit
31c5cec55b
26 changed files with 75 additions and 286 deletions
|
@ -887,7 +887,7 @@ struct port_set<T: send> : recv<T> {
|
|||
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 @@ struct port_set<T: send> : recv<T> {
|
|||
|
||||
fn recv() -> T {
|
||||
match move self.try_recv() {
|
||||
some(x) { move x }
|
||||
some(copy x) { move x }
|
||||
none { fail ~"port_set: endpoints closed" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ export arena, arena_with_size;
|
|||
|
||||
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<T>(&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 @@ impl arena for arena {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn alloc(tydesc: *()) -> *() {
|
||||
fn alloc<T>(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::<T>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ pure fn def_id_of_def(d: def) -> 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)
|
||||
}
|
||||
|
|
|
@ -395,11 +395,6 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
|||
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)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
|
|||
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 @@ class parser {
|
|||
}
|
||||
} 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") {
|
||||
|
|
|
@ -1190,13 +1190,6 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
|
|||
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);
|
||||
|
|
|
@ -361,10 +361,6 @@ fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
|
|||
|
||||
fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
||||
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) {
|
||||
|
|
|
@ -366,7 +366,7 @@ impl of tr for 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))
|
||||
|
|
|
@ -178,7 +178,7 @@ impl public_methods for borrowck_ctxt {
|
|||
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 @@ impl public_methods for borrowck_ctxt {
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 @@ class liveness {
|
|||
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(*) |
|
||||
|
|
|
@ -15,11 +15,11 @@ import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param,
|
|||
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 @@ class Resolver {
|
|||
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 @@ class Resolver {
|
|||
// 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 @@ class Resolver {
|
|||
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.
|
||||
}
|
||||
|
|
|
@ -2411,7 +2411,7 @@ fn trans_local_var(cx: block, def: ast::def) -> local_var_result {
|
|||
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 trans_expr(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");
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<def> {
|
|||
fn local_node_id_to_def_id(fcx: fn_ctxt, i: node_id) -> option<def_id> {
|
||||
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 }
|
||||
|
|
|
@ -70,7 +70,7 @@ import astconv::{ast_conv, ast_path_to_ty, ast_ty_to_ty};
|
|||
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 check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -161,72 +161,3 @@ fn replace_bound_regions_in_fn_ty(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
return arena.alloc(
|
||||
|| node(bottom_up_tree(arena, 2 * item - 1, depth - 1),
|
||||
bottom_up_tree(arena, 2 * item, depth - 1),
|
||||
item);
|
||||
item));
|
||||
}
|
||||
return new(*arena) nil;
|
||||
return arena.alloc(|| nil);
|
||||
}
|
||||
|
||||
fn main(args: ~[~str]) {
|
||||
|
|
9
src/test/compile-fail/borrowck-unary-move-2.rs
Normal file
9
src/test/compile-fail/borrowck-unary-move-2.rs
Normal file
|
@ -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
|
||||
}
|
11
src/test/compile-fail/borrowck-unary-move.rs
Normal file
11
src/test/compile-fail/borrowck-unary-move.rs
Normal file
|
@ -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() {
|
||||
}
|
|
@ -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(*()) -> *()`
|
||||
}
|
|
@ -3,7 +3,7 @@ import std::arena::arena;
|
|||
|
||||
fn main() {
|
||||
let p = &arena();
|
||||
let x = new(*p) 4u;
|
||||
let x = p.alloc(|| 4u);
|
||||
io::print(fmt!{"%u", *x});
|
||||
assert *x == 4u;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std;
|
||||
import libc, sys, unsafe;
|
||||
|
||||
enum arena = ();
|
||||
import std::arena::arena;
|
||||
|
||||
type bcx = {
|
||||
fcx: &fcx
|
||||
|
@ -15,34 +15,19 @@ type ccx = {
|
|||
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() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue