diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2012-03-14 15:16:46 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-03-20 20:39:40 -0700 |
| commit | cfcbec3cc3bde0b8e811520e3bd842f53c2c9e26 (patch) | |
| tree | f6b837b27e979fabfca3bc1df10a2b742d42d351 /src/rustc | |
| parent | ba39e277e2c63909cb35a0dd68e9f3bab728c425 (diff) | |
| download | rust-cfcbec3cc3bde0b8e811520e3bd842f53c2c9e26.tar.gz rust-cfcbec3cc3bde0b8e811520e3bd842f53c2c9e26.zip | |
Implement an initial version of placement new.
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/middle/resolve.rs | 3 | ||||
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 104 | ||||
| -rw-r--r-- | src/rustc/middle/trans/native.rs | 23 | ||||
| -rw-r--r-- | src/rustc/middle/trans/type_use.rs | 3 | ||||
| -rw-r--r-- | src/rustc/middle/tstate/ann.rs | 8 | ||||
| -rw-r--r-- | src/rustc/middle/tstate/auxiliary.rs | 6 | ||||
| -rw-r--r-- | src/rustc/middle/tstate/pre_post_conditions.rs | 3 | ||||
| -rw-r--r-- | src/rustc/middle/tstate/states.rs | 3 | ||||
| -rw-r--r-- | src/rustc/middle/tstate/tritv.rs | 22 | ||||
| -rw-r--r-- | src/rustc/middle/typeck.rs | 51 | ||||
| -rw-r--r-- | src/rustc/syntax/ast.rs | 4 | ||||
| -rw-r--r-- | src/rustc/syntax/fold.rs | 5 | ||||
| -rw-r--r-- | src/rustc/syntax/parse/parser.rs | 9 | ||||
| -rw-r--r-- | src/rustc/syntax/print/pprust.rs | 7 | ||||
| -rw-r--r-- | src/rustc/syntax/visit.rs | 4 |
15 files changed, 199 insertions, 56 deletions
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index e2bb5494659..bfc6be48253 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -2308,6 +2308,9 @@ fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) { ast::expr_assign_op(_, _, _) | ast::expr_index(_, _) { e.impl_map.insert(x.id, sc); } + ast::expr_new(p, _, _) { + e.impl_map.insert(p.id, sc); + } _ {} } visit::visit_expr(x, sc, v); diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index a3b8dfd2154..c0dbdc96210 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1261,9 +1261,9 @@ fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr, some(origin) { let callee_id = ast_util::op_expr_callee_id(un_expr); let fty = node_id_type(bcx, callee_id); - ret trans_call_inner(bcx, fty, {|bcx| + ret trans_call_inner(bcx, fty, expr_ty(bcx, un_expr), {|bcx| impl::trans_method_callee(bcx, callee_id, e, origin) - }, [], un_expr.id, dest); + }, arg_exprs([]), dest); } _ {} } @@ -1450,10 +1450,10 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop, some(origin) { let callee_id = ast_util::op_expr_callee_id(ex); let fty = node_id_type(bcx, callee_id); - ret trans_call_inner(bcx, fty, {|bcx| + ret trans_call_inner(bcx, fty, expr_ty(bcx, ex), {|bcx| // FIXME provide the already-computed address, not the expr impl::trans_method_callee(bcx, callee_id, dst, origin) - }, [src], ex.id, save_in(lhs_res.val)); + }, arg_exprs([src]), save_in(lhs_res.val)); } _ {} } @@ -1561,9 +1561,9 @@ fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr, some(origin) { let callee_id = ast_util::op_expr_callee_id(ex); let fty = node_id_type(bcx, callee_id); - ret trans_call_inner(bcx, fty, {|bcx| + ret trans_call_inner(bcx, fty, expr_ty(bcx, ex), {|bcx| impl::trans_method_callee(bcx, callee_id, lhs, origin) - }, [rhs], ex.id, dest); + }, arg_exprs([rhs]), dest); } _ {} } @@ -2498,6 +2498,10 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr, ret rslt(bcx, val); } +enum call_args { + arg_exprs([@ast::expr]), + arg_vals([ValueRef]) +} // NB: must keep 4 fns in sync: // @@ -2505,12 +2509,12 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr, // - create_llargs_for_fn_args. // - new_fn_ctxt // - trans_args -fn trans_args(cx: block, llenv: ValueRef, es: [@ast::expr], fn_ty: ty::t, +fn trans_args(cx: block, llenv: ValueRef, args: call_args, fn_ty: ty::t, dest: dest, generic_intrinsic: bool) -> {bcx: block, args: [ValueRef], retslot: ValueRef} { let temp_cleanups = []; - let args = ty::ty_fn_args(fn_ty); + let arg_tys = ty::ty_fn_args(fn_ty); let llargs: [ValueRef] = []; let ccx = cx.ccx(); @@ -2546,13 +2550,21 @@ fn trans_args(cx: block, llenv: ValueRef, es: [@ast::expr], fn_ty: ty::t, // First we figure out the caller's view of the types of the arguments. // This will be needed if this is a generic call, because the callee has // to cast her view of the arguments to the caller's view. - let arg_tys = type_of_explicit_args(ccx, args); - let i = 0u; - for e: @ast::expr in es { - let r = trans_arg_expr(bcx, args[i], arg_tys[i], e, temp_cleanups); - bcx = r.bcx; - llargs += [r.val]; - i += 1u; + alt args { + arg_exprs(es) { + let llarg_tys = type_of_explicit_args(ccx, arg_tys); + let i = 0u; + for e: @ast::expr in es { + let r = trans_arg_expr(bcx, arg_tys[i], llarg_tys[i], + e, temp_cleanups); + bcx = r.bcx; + llargs += [r.val]; + i += 1u; + } + } + arg_vals(vs) { + llargs += vs; + } } // now that all arguments have been successfully built, we can revoke any @@ -2568,15 +2580,15 @@ fn trans_args(cx: block, llenv: ValueRef, es: [@ast::expr], fn_ty: ty::t, } fn trans_call(in_cx: block, f: @ast::expr, - args: [@ast::expr], id: ast::node_id, dest: dest) + args: call_args, id: ast::node_id, dest: dest) -> block { - trans_call_inner(in_cx, expr_ty(in_cx, f), - {|cx| trans_callee(cx, f)}, args, id, dest) + trans_call_inner(in_cx, expr_ty(in_cx, f), node_id_type(in_cx, id), + {|cx| trans_callee(cx, f)}, args, dest) } -fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, +fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, ret_ty: ty::t, get_callee: fn(block) -> lval_maybe_callee, - args: [@ast::expr], id: ast::node_id, dest: dest) + args: call_args, dest: dest) -> block { with_scope(in_cx, "call") {|cx| let f_res = get_callee(cx); @@ -2603,9 +2615,10 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, } }; - let ret_ty = node_id_type(bcx, id); - let args_res = trans_args(bcx, llenv, args, fn_expr_ty, dest, - option::is_some(f_res.tds)); + let args_res = { + trans_args(bcx, llenv, args, fn_expr_ty, dest, + option::is_some(f_res.tds)) + }; bcx = args_res.bcx; let llargs = args_res.args; option::may(f_res.tds) {|vals| @@ -2923,7 +2936,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block { } ast::expr_cast(val, _) { ret trans_cast(bcx, val, e.id, dest); } ast::expr_call(f, args, _) { - ret trans_call(bcx, f, args, e.id, dest); + ret trans_call(bcx, f, arg_exprs(args), e.id, dest); } ast::expr_field(base, _, _) { if dest == ignore { ret trans_expr(bcx, base, ignore); } @@ -2937,9 +2950,9 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block { let origin = bcx.ccx().maps.method_map.get(e.id); let callee_id = ast_util::op_expr_callee_id(e); let fty = node_id_type(bcx, callee_id); - ret trans_call_inner(bcx, fty, {|bcx| + ret trans_call_inner(bcx, fty, expr_ty(bcx, e), {|bcx| impl::trans_method_callee(bcx, callee_id, base, origin) - }, [idx], e.id, dest); + }, arg_exprs([idx]), dest); } // These return nothing @@ -3037,6 +3050,45 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block { assert dest == ignore; ret trans_assign_op(bcx, e, op, dst, src); } + ast::expr_new(pool, alloc_id, val) { + // First, call pool->alloc(sz, align) 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 {bcx, val: ptr_ptr_val} = alloc_ty(bcx, ptr_ty); + + #debug["ptr_ty = %s", ty_to_str(tcx, ptr_ty)]; + #debug["ptr_ptr_val = %s", val_str(ccx.tn, ptr_ptr_val)]; + + let void_ty = ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), + mutbl: ast::m_imm}); + let voidval = { + let llvoid_ty = type_of(ccx, void_ty); + PointerCast(bcx, ptr_ptr_val, T_ptr(llvoid_ty)) + }; + + #debug["voidval = %s", val_str(ccx.tn, voidval)]; + + let llval_ty = type_of(ccx, expr_ty(bcx, val)); + let args = [llsize_of(ccx, llval_ty), llalign_of(ccx, llval_ty)]; + let origin = bcx.ccx().maps.method_map.get(alloc_id); + let bcx = trans_call_inner( + bcx, + node_id_type(bcx, alloc_id), + void_ty, + {|bcx| impl::trans_method_callee(bcx, alloc_id, pool, origin) }, + arg_vals(args), + 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/native.rs b/src/rustc/middle/trans/native.rs index 938514c93b9..738879b8d8a 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -111,27 +111,28 @@ fn classify_ty(ty: TypeRef) -> [x86_64_reg_class] { } } - fn unify(cls: [mut x86_64_reg_class], i: uint, - new: x86_64_reg_class) { - if cls[i] == new { + fn unify(cls: [mut x86_64_reg_class], + i: uint, + newv: x86_64_reg_class) { + if cls[i] == newv { ret; } else if cls[i] == no_class { - cls[i] = new; - } else if new == no_class { + cls[i] = newv; + } else if newv == no_class { ret; - } else if cls[i] == memory_class || new == memory_class { + } else if cls[i] == memory_class || newv == memory_class { cls[i] = memory_class; - } else if cls[i] == integer_class || new == integer_class { + } else if cls[i] == integer_class || newv == integer_class { cls[i] = integer_class; } else if cls[i] == x87_class || cls[i] == x87up_class || cls[i] == complex_x87_class || - new == x87_class || - new == x87up_class || - new == complex_x87_class { + newv == x87_class || + newv == x87up_class || + newv == complex_x87_class { cls[i] = memory_class; } else { - cls[i] = new; + cls[i] = newv; } } diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 99ccdeeb70e..68779c7e71e 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -168,6 +168,9 @@ 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_for(_, _, _) | expr_do_while(_, _) | expr_alt(_, _, _) | expr_block(_) | expr_if(_, _, _) | expr_while(_, _) | expr_fail(_) | expr_break | expr_cont | expr_unary(_, _) | diff --git a/src/rustc/middle/tstate/ann.rs b/src/rustc/middle/tstate/ann.rs index f3862e3d20f..82388f9b89f 100644 --- a/src/rustc/middle/tstate/ann.rs +++ b/src/rustc/middle/tstate/ann.rs @@ -183,14 +183,14 @@ fn set_poststate(a: ts_ann, p: poststate) -> bool { // Set all the bits in p that are set in new -fn extend_prestate(p: prestate, new: poststate) -> bool { - ret tritv_union(p, new); +fn extend_prestate(p: prestate, newv: poststate) -> bool { + ret tritv_union(p, newv); } // Set all the bits in p that are set in new -fn extend_poststate(p: poststate, new: poststate) -> bool { - ret tritv_union(p, new); +fn extend_poststate(p: poststate, newv: poststate) -> bool { + ret tritv_union(p, newv); } // Sets the given bit in p to "don't care" diff --git a/src/rustc/middle/tstate/auxiliary.rs b/src/rustc/middle/tstate/auxiliary.rs index 38bfb1e4f71..e6f5ca1dd64 100644 --- a/src/rustc/middle/tstate/auxiliary.rs +++ b/src/rustc/middle/tstate/auxiliary.rs @@ -709,8 +709,8 @@ fn find_instances(_fcx: fn_ctxt, subst: subst, c: constraint) -> for d: pred_args in *descs { if args_mention(d.node.args, find_in_subst_bool, subst) { let old_bit_num = d.node.bit_num; - let new = replace(subst, d); - alt find_instance_(new, *descs) { + let newv = replace(subst, d); + alt find_instance_(newv, *descs) { some(d1) { rslt += [{from: old_bit_num, to: d1}]; } _ { } } @@ -753,7 +753,7 @@ fn replace(subst: subst, d: pred_args) -> [constr_arg_general_<inst>] { alt c.node { carg_ident(p) { alt find_in_subst(p.node, subst) { - some(new) { rslt += [carg_ident(new)]; } + some(newv) { rslt += [carg_ident(newv)]; } _ { rslt += [c.node]; } } } diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs index 5b6d5cc2911..89e7409ed96 100644 --- a/src/rustc/middle/tstate/pre_post_conditions.rs +++ b/src/rustc/middle/tstate/pre_post_conditions.rs @@ -325,6 +325,9 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) { clear_pp(rslt); handle_var(fcx, rslt, e.id, path_to_ident(p)); } + expr_new(p, _, v) { + find_pre_post_exprs(fcx, [p, v], e.id); + } expr_log(_, lvl, arg) { find_pre_post_exprs(fcx, [lvl, arg], e.id); } diff --git a/src/rustc/middle/tstate/states.rs b/src/rustc/middle/tstate/states.rs index d7148563d02..7bb16a5ec9e 100644 --- a/src/rustc/middle/tstate/states.rs +++ b/src/rustc/middle/tstate/states.rs @@ -355,6 +355,9 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool { let num_constrs = num_constraints(fcx.enclosing); alt e.node { + expr_new(p, _, v) { + ret find_pre_post_state_two(fcx, pres, p, v, e.id, oper_pure); + } expr_vec(elts, _) { ret find_pre_post_state_exprs(fcx, pres, e.id, vec::from_elem(vec::len(elts), diff --git a/src/rustc/middle/tstate/tritv.rs b/src/rustc/middle/tstate/tritv.rs index e9170033fb7..98b27e0e3ba 100644 --- a/src/rustc/middle/tstate/tritv.rs +++ b/src/rustc/middle/tstate/tritv.rs @@ -155,8 +155,8 @@ fn trit_and(a: trit, b: trit) -> trit { // a and b were both dont_care } -fn change(changed: bool, old: trit, new: trit) -> bool { - changed || new != old +fn change(changed: bool, old: trit, newv: trit) -> bool { + changed || newv != old } fn tritv_difference(p1: t, p2: t) -> bool { @@ -166,9 +166,9 @@ fn tritv_difference(p1: t, p2: t) -> bool { let changed = false; while i < sz { let old = tritv_get(p1, i); - let new = trit_minus(old, tritv_get(p2, i)); - changed = change(changed, old, new); - tritv_set(i, p1, new); + let newv = trit_minus(old, tritv_get(p2, i)); + changed = change(changed, old, newv); + tritv_set(i, p1, newv); i += 1u; } ret changed; @@ -181,9 +181,9 @@ fn tritv_union(p1: t, p2: t) -> bool { let changed = false; while i < sz { let old = tritv_get(p1, i); - let new = trit_or(old, tritv_get(p2, i)); - changed = change(changed, old, new); - tritv_set(i, p1, new); + let newv = trit_or(old, tritv_get(p2, i)); + changed = change(changed, old, newv); + tritv_set(i, p1, newv); i += 1u; } ret changed; @@ -196,9 +196,9 @@ fn tritv_intersect(p1: t, p2: t) -> bool { let changed = false; while i < sz { let old = tritv_get(p1, i); - let new = trit_and(old, tritv_get(p2, i)); - changed = change(changed, old, new); - tritv_set(i, p1, new); + let newv = trit_and(old, tritv_get(p2, i)); + changed = change(changed, old, newv); + tritv_set(i, p1, newv); i += 1u; } ret changed; diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 87bb55e1b76..a6c23cdca58 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -1888,6 +1888,12 @@ fn lookup_method_inner(fcx: @fn_ctxt, expr: @ast::expr, origin: method_origin, self_sub: option<self_subst>}> { let tcx = fcx.ccx.tcx; + + #debug["lookup_method_inner: expr=%s name=%s ty=%s", + expr_to_str(expr), + name, + ty_to_str(fcx.ccx.tcx, ty)]; + // First, see whether this is an interface-bounded parameter alt ty::get(ty).struct { ty::ty_param(n, did) { @@ -2870,6 +2876,51 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } } } + ast::expr_new(p, alloc_id, v) { + bot |= check_expr(fcx, p); + bot |= check_expr(fcx, v); + + let p_ty = expr_ty(tcx, p); + + alt lookup_method(fcx, p, alloc_id, "alloc", p_ty, []) { + some(origin) { + fcx.ccx.method_map.insert(alloc_id, origin); + + // Check that the alloc() method has the expected type, which + // should be fn(sz: uint, align: uint) -> *(). + let expected_ty = { + let ty_uint = ty::mk_uint(tcx); + 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_uint)); + ty::mk_fn(tcx, {proto: ast::proto_any, + inputs: [{mode: m, ty: ty_uint}, + {mode: m, ty: ty_uint}], + output: ty_nilp, + ret_style: ast::return_val, + constraints: []}) + }; + + demand::simple(fcx, expr.span, + expected_ty, node_id_to_type(tcx, alloc_id)); + } + + none { + let t_err = resolve_type_vars_if_possible(fcx, p_ty); + let msg = #fmt["no `alloc()` method found for type `%s`", + ty_to_str(tcx, 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 = expr_ty(tcx, v); + let res_ty = ty::mk_rptr(tcx, pool_region, {ty: v_ty, + mutbl: ast::m_imm}); + write_ty(tcx, expr.id, res_ty); + } } if bot { write_ty(tcx, expr.id, ty::mk_bot(tcx)); } diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs index db0f6a56d80..93f60519114 100644 --- a/src/rustc/syntax/ast.rs +++ b/src/rustc/syntax/ast.rs @@ -325,6 +325,10 @@ enum expr_ { expr_be(@expr), expr_log(int, @expr, @expr), + expr_new(/* arena */ @expr, + /* id for the alloc() call */ node_id, + /* value */ @expr), + /* just an assert, no significance to typestate */ expr_assert(@expr), diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs index 9b80775343e..ab5659b1ff4 100644 --- a/src/rustc/syntax/fold.rs +++ b/src/rustc/syntax/fold.rs @@ -382,6 +382,11 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { let fold_mac = bind fold_mac_(_, fld); ret alt e { + expr_new(p, i, v) { + expr_new(fld.fold_expr(p), + fld.new_id(i), + fld.fold_expr(v)) + } expr_vec(exprs, mutt) { expr_vec(fld.map_exprs(fld.fold_expr, exprs), mutt) } diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs index 4fe7aade41c..99746aed84a 100644 --- a/src/rustc/syntax/parse/parser.rs +++ b/src/rustc/syntax/parse/parser.rs @@ -150,7 +150,7 @@ fn bad_expr_word_table() -> hashmap<str, ()> { "enum", "export", "fail", "fn", "for", "if", "iface", "impl", "import", "let", "log", "loop", "mod", "mut", "mutable", "native", "pure", "resource", "ret", "trait", - "type", "unchecked", "unsafe", "while"] { + "type", "unchecked", "unsafe", "while", "new"] { words.insert(word, ()); } words @@ -852,6 +852,13 @@ fn parse_bottom_expr(p: parser) -> pexpr { let blk = parse_block_tail(p, lo, ast::default_blk); ret mk_pexpr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk)); } + } else if eat_word(p, "new") { + expect(p, token::LPAREN); + let r = parse_expr(p); + expect(p, token::RPAREN); + let v = parse_expr(p); + ret mk_pexpr(p, lo, p.span.hi, + ast::expr_new(r, p.get_id(), v)); } else if eat_word(p, "if") { ret pexpr(parse_if_expr(p)); } else if eat_word(p, "for") { diff --git a/src/rustc/syntax/print/pprust.rs b/src/rustc/syntax/print/pprust.rs index e10262117a4..6bdd4d84306 100644 --- a/src/rustc/syntax/print/pprust.rs +++ b/src/rustc/syntax/print/pprust.rs @@ -1089,6 +1089,13 @@ 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); diff --git a/src/rustc/syntax/visit.rs b/src/rustc/syntax/visit.rs index c0b7eea6ace..fa3c043d647 100644 --- a/src/rustc/syntax/visit.rs +++ b/src/rustc/syntax/visit.rs @@ -315,6 +315,10 @@ 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_vec(es, _) { visit_exprs(es, e, v); } expr_rec(flds, base) { for f: field in flds { v.visit_expr(f.node.expr, e, v); } |
