diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 3a308011e75bb..e9441bfd4dfdc 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -355,7 +355,7 @@ impl ast::def: tr { ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) } ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) } ast::def_const(did) => { ast::def_const(did.tr(xcx)) } - ast::def_arg(nid, m) => { ast::def_arg(xcx.tr_id(nid), m) } + ast::def_arg(nid, m, b) => { ast::def_arg(xcx.tr_id(nid), m, b) } ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) } ast::def_variant(e_did, v_did) => { ast::def_variant(e_did.tr(xcx), v_did.tr(xcx)) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index da1f82a33b759..fbb0b421754f8 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -283,7 +283,7 @@ enum VarKind { fn relevant_def(def: def) -> Option { match def { def_binding(nid, _) | - def_arg(nid, _) | + def_arg(nid, _, _) | def_local(nid, _) | def_self(nid, _) => Some(nid), diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 04c57025157ab..b069c3cda98bc 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -583,18 +583,19 @@ impl &mem_categorization_ctxt { mutbl:m_imm, ty:expr_ty} } - ast::def_arg(vid, mode) => { + ast::def_arg(vid, mode, mutbl) => { // Idea: make this could be rewritten to model by-ref // stuff as `&const` and `&mut`? // m: mutability of the argument // lp: loan path, must be none for aliasable things - let {m,lp} = match ty::resolved_mode(self.tcx, mode) { + let m = if mutbl {m_mutbl} else {m_imm}; + let lp = match ty::resolved_mode(self.tcx, mode) { ast::by_move | ast::by_copy => { - {m: m_imm, lp: Some(@lp_arg(vid))} + Some(@lp_arg(vid)) } ast::by_ref => { - {m: m_imm, lp: None} + None } ast::by_val => { // by-value is this hybrid mode where we have a @@ -602,7 +603,7 @@ impl &mem_categorization_ctxt { // considered loanable because, for example, a by-ref // and and by-val argument might both actually contain // the same unique ptr. - {m: m_imm, lp: None} + None } }; @{id:id, span:span, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ffb696ec4f946..e2a2b8bd93d87 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4154,9 +4154,11 @@ impl Resolver { for declaration.inputs.each |argument| { let binding_mode = ArgumentIrrefutableMode(argument.mode); + let mutability = + if argument.is_mutbl {Mutable} else {Immutable}; self.resolve_pattern(argument.pat, binding_mode, - Immutable, + mutability, None, visitor); @@ -4340,12 +4342,7 @@ impl Resolver { } fn resolve_local(local: @local, visitor: ResolveVisitor) { - let mut mutability; - if local.node.is_mutbl { - mutability = Mutable; - } else { - mutability = Immutable; - } + let mutability = if local.node.is_mutbl {Mutable} else {Immutable}; // Resolve the type. self.resolve_type(local.node.ty, visitor); @@ -4606,7 +4603,8 @@ impl Resolver { } ArgumentIrrefutableMode(argument_mode) => { // And for function arguments, `def_arg`. - def_arg(pattern.id, argument_mode) + def_arg(pattern.id, argument_mode, + is_mutable) } }; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 6c042d740e1f5..c2a88a82e79b8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1708,6 +1708,7 @@ fn trans_enum_variant(ccx: @crate_ctxt, // Translate variant arguments to function arguments. let fn_args = vec::map(args, |varg| {mode: ast::expl(ast::by_copy), + is_mutbl: false, ty: varg.ty, pat: ast_util::ident_to_pat(ccx.tcx.sess.next_node_id(), ast_util::dummy_sp(), @@ -1766,6 +1767,7 @@ fn trans_tuple_struct(ccx: @crate_ctxt, let fn_args = do fields.map |field| { { mode: ast::expl(ast::by_copy), + is_mutbl: false, ty: field.node.ty, pat: ast_util::ident_to_pat(ccx.tcx.sess.next_node_id(), ast_util::dummy_sp(), diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index d3a1772a6b0f8..69356b72c424a 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -830,7 +830,7 @@ fn trans_local_var(bcx: block, } } } - ast::def_arg(nid, _) => { + ast::def_arg(nid, _, _) => { take_local(bcx, bcx.fcx.llargs, nid, expr_id_opt) } ast::def_local(nid, _) | ast::def_binding(nid, _) => { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index df7444ee6e94a..d94f45693ed7f 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2740,7 +2740,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> ty_param_bounds_and_ty { match defn { - ast::def_arg(nid, _) | ast::def_local(nid, _) | + ast::def_arg(nid, _, _) | ast::def_local(nid, _) | ast::def_self(nid, _) | ast::def_binding(nid, _) => { assert (fcx.inh.locals.contains_key(nid)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, nid)); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 797a21c38e20b..2be94eb801ff5 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -49,8 +49,8 @@ type rvt = visit::vt<@rcx>; fn encl_region_of_def(fcx: @fn_ctxt, def: ast::def) -> ty::Region { let tcx = fcx.tcx(); match def { - def_local(node_id, _) | def_arg(node_id, _) | def_self(node_id, _) | - def_binding(node_id, _) => + def_local(node_id, _) | def_arg(node_id, _, _) | + def_self(node_id, _) | def_binding(node_id, _) => return encl_region(tcx, node_id), def_upvar(_, subdef, closure_id, body_id) => { match ty_fn_proto(fcx.node_ty(closure_id)) { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c7c8c77c70fa3..aa686a36c89e2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -127,7 +127,7 @@ enum def { def_mod(def_id), def_foreign_mod(def_id), def_const(def_id), - def_arg(node_id, mode), + def_arg(node_id, mode, bool /* is_mutbl */), def_local(node_id, bool /* is_mutbl */), def_variant(def_id /* enum */, def_id /* variant */), def_ty(def_id), @@ -191,9 +191,10 @@ impl def : cmp::Eq { _ => false } } - def_arg(e0a, e1a) => { + def_arg(e0a, e1a, e2a) => { match (*other) { - def_arg(e0b, e1b) => e0a == e0b && e1a == e1b, + def_arg(e0b, e1b, e2b) => + e0a == e0b && e1a == e1b && e2a == e2b, _ => false } } @@ -1138,7 +1139,7 @@ impl Ty : to_bytes::IterBytes { #[auto_encode] #[auto_decode] -type arg = {mode: mode, ty: @Ty, pat: @pat, id: node_id}; +type arg = {mode: mode, is_mutbl: bool, ty: @Ty, pat: @pat, id: node_id}; #[auto_encode] #[auto_decode] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index eaa61b304cd16..1e8880d189fd9 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -81,7 +81,7 @@ pure fn def_id_of_def(d: def) -> def_id { def_use(id) | def_struct(id) => { id } - def_arg(id, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id) + def_arg(id, _, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id) | def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id) | def_typaram_binder(id) | def_label(id) => { local_def(id) diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index b8fe00e246c7c..af9f4ca2c7c4c 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -540,6 +540,7 @@ fn mk_ser_method( let ser_inputs = ~[{ mode: ast::infer(cx.next_id()), + is_mutbl: false, ty: ty_s, pat: @{id: cx.next_id(), node: ast::pat_ident( @@ -600,6 +601,7 @@ fn mk_deser_method( let deser_inputs = ~[{ mode: ast::infer(cx.next_id()), + is_mutbl: false, ty: ty_d, pat: @{id: cx.next_id(), node: ast::pat_ident( @@ -1120,6 +1122,7 @@ fn mk_enum_deser_body( { inputs: ~[{ mode: ast::infer(cx.next_id()), + is_mutbl: false, ty: @{ id: cx.next_id(), node: ast::ty_infer, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index d63f14b57749a..a7cb102f090d4 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -287,6 +287,7 @@ fn mk_arg(cx: ext_ctxt, let arg_pat = mk_pat_ident(cx, span, ident); { mode: ast::infer(cx.next_id()), + is_mutbl: false, ty: ty, pat: arg_pat, id: cx.next_id() diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 7a87d909fe677..eafde9cbb0825 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -178,6 +178,7 @@ impl ext_ctxt: ext_ctxt_ast_builder { fn arg(name: ident, ty: @ast::Ty) -> ast::arg { {mode: ast::infer(self.next_id()), + is_mutbl: false, ty: ty, pat: @{id: self.next_id(), node: ast::pat_ident( diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6d32c73e1f703..37bea4547590b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -116,6 +116,7 @@ fn fold_attribute_(at: attribute, fld: ast_fold) -> //used in noop_fold_foreign_item and noop_fold_fn_decl fn fold_arg_(a: arg, fld: ast_fold) -> arg { return {mode: a.mode, + is_mutbl: a.is_mutbl, ty: fld.fold_ty(a.ty), pat: fld.fold_pat(a.pat), id: fld.new_id(a.id)}; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f85ca3fefef88..c0a6b3e401df6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -684,8 +684,10 @@ impl Parser { // identifier names. fn parse_arg_general(require_name: bool) -> arg { let mut m; + let mut is_mutbl = false; let pat = if require_name || self.is_named_argument() { m = self.parse_arg_mode(); + is_mutbl = self.eat_keyword(~"mut"); let pat = self.parse_pat(false); self.expect(token::COLON); pat @@ -698,7 +700,7 @@ impl Parser { let t = self.parse_ty(false); - {mode: m, ty: t, pat: pat, id: self.get_id()} + {mode: m, is_mutbl: is_mutbl, ty: t, pat: pat, id: self.get_id()} } fn parse_arg() -> arg_or_capture_item { @@ -720,7 +722,8 @@ impl Parser { node: ty_infer, span: mk_sp(p.span.lo, p.span.hi)} }; - either::Left({mode: m, ty: t, pat: pat, id: p.get_id()}) + either::Left({mode: m, is_mutbl: false, ty: t, pat: pat, + id: p.get_id()}) } }