]> git.lizzy.rs Git - rust.git/commitdiff
libsyntax/librustc: Allow mut qualifier in patterns.
authorLuqman Aden <laden@csclub.uwaterloo.ca>
Sun, 20 Oct 2013 12:31:23 +0000 (08:31 -0400)
committerLuqman Aden <laden@csclub.uwaterloo.ca>
Fri, 25 Oct 2013 05:21:07 +0000 (01:21 -0400)
20 files changed:
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/check_match.rs
src/librustc/middle/kind.rs
src/librustc/middle/lint.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/moves.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/typeck/check/_match.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic.rs
src/libsyntax/ext/expand.rs
src/libsyntax/fold.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs

index 6c927794dc8117f7e568747fdfbd8d19fe159602..ea5c05e9ec80e6b67645372e4d303b1050bd0cd3 100644 (file)
@@ -727,7 +727,7 @@ fn gather_pat(&mut self,
                                          loan_mutability,
                                          scope_r);
                   }
-                  ast::BindInfer => {
+                  ast::BindByValue(_) => {
                       // No borrows here, but there may be moves
                       if self.bccx.is_move(pat.id) {
                           gather_moves::gather_move_from_pat(
index de5e00d241eb1d09ae7cb221277d914564fcf8ca..482ba43ae259ddbba93ea3ba8f7aee7a4eadbb99 100644 (file)
@@ -884,7 +884,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
                 BindByRef(_) => {
                     by_ref_span = Some(span);
                 }
-                BindInfer => {
+                BindByValue(_) => {
                     if cx.moves_map.contains(&id) {
                         any_by_move = true;
                     }
index 5737039f83c3556a5e387023f7e7a2ed6572e2c5..fd5114889fddbe98045a60547db3936367d055d3 100644 (file)
@@ -432,14 +432,12 @@ fn is_nullary_variant(cx: &Context, ex: @Expr) -> bool {
 
 fn check_imm_free_var(cx: &Context, def: Def, sp: Span) {
     match def {
-        DefLocal(_, is_mutbl) => {
-            if is_mutbl {
-                cx.tcx.sess.span_err(
-                    sp,
-                    "mutable variables cannot be implicitly captured");
-            }
+        DefLocal(_, BindByValue(MutMutable)) => {
+            cx.tcx.sess.span_err(
+                sp,
+                "mutable variables cannot be implicitly captured");
         }
-        DefArg(*) => { /* ok */ }
+        DefLocal(*) | DefArg(*) => { /* ok */ }
         DefUpvar(_, def1, _, _) => { check_imm_free_var(cx, *def1, sp); }
         DefBinding(*) | DefSelf(*) => { /*ok*/ }
         _ => {
index b0cdd53de922c82347f23501266c9c8f5cf21188..ccabfe28dd7b41959cc41c737d22939aac36e744 100644 (file)
@@ -813,28 +813,32 @@ fn check_unused_unsafe(cx: &Context, e: &ast::Expr) {
 }
 
 fn check_unused_mut_pat(cx: &Context, p: @ast::Pat) {
-    let mut used = false;
-    let mut bindings = 0;
-    do pat_util::pat_bindings(cx.tcx.def_map, p) |_, id, _, _| {
-        used = used || cx.tcx.used_mut_nodes.contains(&id);
-        bindings += 1;
-    }
-    if !used {
-        let msg = if bindings == 1 {
-            "variable does not need to be mutable"
-        } else {
-            "variables do not need to be mutable"
-        };
-        cx.span_lint(unused_mut, p.span, msg);
-    }
-}
-
-fn check_unused_mut_fn_decl(cx: &Context, fd: &ast::fn_decl) {
-    for arg in fd.inputs.iter() {
-        if arg.is_mutbl {
-            check_unused_mut_pat(cx, arg.pat);
+    fn check_unused_mut_pat_inner(cx: &Context, p: @ast::Pat) {
+        let mut used = false;
+        let mut bindings = 0;
+        do pat_util::pat_bindings(cx.tcx.def_map, p) |_, id, _, _| {
+            used = used || cx.tcx.used_mut_nodes.contains(&id);
+            bindings += 1;
+        }
+        if !used {
+            let msg = if bindings == 1 {
+                "variable does not need to be mutable"
+            } else {
+                "variables do not need to be mutable"
+            };
+            cx.span_lint(unused_mut, p.span, msg);
         }
     }
+    do ast_util::walk_pat(p) |pat| {
+        match pat.node {
+            ast::PatIdent(ast::BindByValue(ast::MutMutable), _, _) => {
+                check_unused_mut_pat_inner(cx, pat);
+            }
+            _ => {}
+        }
+
+        true
+    };
 }
 
 fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
@@ -1075,6 +1079,8 @@ fn visit_item(&mut self, it: @ast::item, _: ()) {
 
     fn visit_pat(&mut self, p: @ast::Pat, _: ()) {
         check_pat_non_uppercase_statics(self, p);
+        check_unused_mut_pat(self, p);
+
         visit::walk_pat(self, p, ());
     }
 
@@ -1095,30 +1101,9 @@ fn visit_stmt(&mut self, s: @ast::Stmt, _: ()) {
         visit::walk_stmt(self, s, ());
     }
 
-    fn visit_ty_method(&mut self, tm: &ast::TypeMethod, _: ()) {
-        check_unused_mut_fn_decl(self, &tm.decl);
-        visit::walk_ty_method(self, tm, ());
-    }
-
-    fn visit_trait_method(&mut self, tm: &ast::trait_method, _: ()) {
-        match *tm {
-            ast::required(ref m) => check_unused_mut_fn_decl(self, &m.decl),
-            ast::provided(ref m) => check_unused_mut_fn_decl(self, &m.decl)
-        }
-        visit::walk_trait_method(self, tm, ());
-    }
-
-    fn visit_local(&mut self, l: @ast::Local, _: ()) {
-        if l.is_mutbl {
-            check_unused_mut_pat(self, l.pat);
-        }
-        visit::walk_local(self, l, ());
-    }
-
     fn visit_fn(&mut self, fk: &visit::fn_kind, decl: &ast::fn_decl,
                 body: &ast::Block, span: Span, id: ast::NodeId, _: ()) {
         let recurse = |this: &mut Context| {
-            check_unused_mut_fn_decl(this, decl);
             visit::walk_fn(this, fk, decl, body, span, id, ());
         };
 
index 695f4a6fd13b5a1ef04571a7d9b8607fb7e8cf76..e9e416124af9fb08fa42ca1634b31024c5b6bfbd 100644 (file)
@@ -429,7 +429,7 @@ fn visit_fn(v: &mut LivenessVisitor,
 
 fn visit_local(v: &mut LivenessVisitor, local: @Local, this: @mut IrMaps) {
     let def_map = this.tcx.def_map;
-    do pat_util::pat_bindings(def_map, local.pat) |_bm, p_id, sp, path| {
+    do pat_util::pat_bindings(def_map, local.pat) |bm, p_id, sp, path| {
         debug!("adding local variable {}", p_id);
         let name = ast_util::path_to_ident(path);
         this.add_live_node_for_node(p_id, VarDefNode(sp));
@@ -437,10 +437,14 @@ fn visit_local(v: &mut LivenessVisitor, local: @Local, this: @mut IrMaps) {
           Some(_) => FromLetWithInitializer,
           None => FromLetNoInitializer
         };
+        let mutbl = match bm {
+            BindByValue(MutMutable) => true,
+            _ => false
+        };
         this.add_variable(Local(LocalInfo {
           id: p_id,
           ident: name,
-          is_mutbl: local.is_mutbl,
+          is_mutbl: mutbl,
           kind: kind
         }));
     }
@@ -454,11 +458,15 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @mut IrMaps) {
             debug!("adding local variable {} from match with bm {:?}",
                    p_id, bm);
             let name = ast_util::path_to_ident(path);
+            let mutbl = match bm {
+                BindByValue(MutMutable) => true,
+                _ => false
+            };
             this.add_live_node_for_node(p_id, VarDefNode(sp));
             this.add_variable(Local(LocalInfo {
                 id: p_id,
                 ident: name,
-                is_mutbl: false,
+                is_mutbl: mutbl,
                 kind: FromMatch(bm)
             }));
         }
index eb03027ad71ffd3b0c1bcc0693e338230e6ac3b6..5e26201522c4111d44d5d570d83c8d7b689f983e 100644 (file)
@@ -473,12 +473,15 @@ pub fn cat_def(&self,
               }
           }
 
-          ast::DefArg(vid, mutbl) => {
+          ast::DefArg(vid, binding_mode) => {
             // Idea: make this could be rewritten to model by-ref
             // stuff as `&const` and `&mut`?
 
             // m: mutability of the argument
-            let m = if mutbl {McDeclared} else {McImmutable};
+            let m = match binding_mode {
+                ast::BindByValue(ast::MutMutable) => McDeclared,
+                _ => McImmutable
+            };
             @cmt_ {
                 id: id,
                 span: span,
@@ -548,25 +551,20 @@ pub fn cat_def(&self,
               }
           }
 
-          ast::DefLocal(vid, mutbl) => {
-            let m = if mutbl {McDeclared} else {McImmutable};
-            @cmt_ {
-                id:id,
-                span:span,
-                cat:cat_local(vid),
-                mutbl:m,
-                ty:expr_ty
-            }
-          }
-
-          ast::DefBinding(vid, _) => {
+          ast::DefLocal(vid, binding_mode) |
+          ast::DefBinding(vid, binding_mode) => {
             // by-value/by-ref bindings are local variables
+            let m = match binding_mode {
+                ast::BindByValue(ast::MutMutable) => McDeclared,
+                _ => McImmutable
+            };
+
             @cmt_ {
-                id:id,
-                span:span,
-                cat:cat_local(vid),
-                mutbl:McImmutable,
-                ty:expr_ty
+                id: id,
+                span: span,
+                cat: cat_local(vid),
+                mutbl: m,
+                ty: expr_ty
             }
           }
         }
index 5001614647a88993af475cc9f2d8e6b41ad1b7a3..d4dce789192d7195c8697b194ff88baa47b08f16 100644 (file)
@@ -618,7 +618,7 @@ pub fn use_pat(&mut self, pat: @Pat) {
         do pat_bindings(self.tcx.def_map, pat) |bm, id, _span, path| {
             let binding_moves = match bm {
                 BindByRef(_) => false,
-                BindInfer => {
+                BindByValue(_) => {
                     let pat_ty = ty::node_id_to_type(self.tcx, id);
                     debug!("pattern {:?} {} type is {}",
                            id,
index ee36b807ac79c358311f26e9524d3efc4ca0853b..c16c39b5a09bab2bf7ddb444f5ba75d2a45a85ca 100644 (file)
@@ -3817,11 +3817,8 @@ fn resolve_function(&mut self,
                 Some(declaration) => {
                     for argument in declaration.inputs.iter() {
                         let binding_mode = ArgumentIrrefutableMode;
-                        let mutability =
-                            if argument.is_mutbl {Mutable} else {Immutable};
                         this.resolve_pattern(argument.pat,
                                              binding_mode,
-                                             mutability,
                                              None);
 
                         this.resolve_type(&argument.ty);
@@ -4036,8 +4033,6 @@ fn resolve_module(&mut self,
     }
 
     fn resolve_local(&mut self, local: @Local) {
-        let mutability = if local.is_mutbl {Mutable} else {Immutable};
-
         // Resolve the type.
         self.resolve_type(&local.ty);
 
@@ -4052,7 +4047,7 @@ fn resolve_local(&mut self, local: @Local) {
         }
 
         // Resolve the pattern.
-        self.resolve_pattern(local.pat, LocalIrrefutableMode, mutability, None);
+        self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
     }
 
     // build a map from pattern identifiers to binding-info's.
@@ -4116,8 +4111,7 @@ fn resolve_arm(&mut self, arm: &Arm) {
 
         let bindings_list = @mut HashMap::new();
         for pattern in arm.pats.iter() {
-            self.resolve_pattern(*pattern, RefutableMode, Immutable,
-                                 Some(bindings_list));
+            self.resolve_pattern(*pattern, RefutableMode, Some(bindings_list));
         }
 
         // This has to happen *after* we determine which
@@ -4261,7 +4255,6 @@ fn resolve_type(&mut self, ty: &Ty) {
     fn resolve_pattern(&mut self,
                        pattern: @Pat,
                        mode: PatternBindingMode,
-                       mutability: Mutability,
                        // Maps idents to the node ID for the (outermost)
                        // pattern that binds them
                        bindings_list: Option<@mut HashMap<Name,NodeId>>) {
@@ -4324,8 +4317,6 @@ struct in scope",
                             debug!("(resolving pattern) binding `{}`",
                                    interner_get(renamed));
 
-                            let is_mutable = mutability == Mutable;
-
                             let def = match mode {
                                 RefutableMode => {
                                     // For pattern arms, we must use
@@ -4335,11 +4326,11 @@ struct in scope",
                                 }
                                 LocalIrrefutableMode => {
                                     // But for locals, we use `def_local`.
-                                    DefLocal(pattern.id, is_mutable)
+                                    DefLocal(pattern.id, binding_mode)
                                 }
                                 ArgumentIrrefutableMode => {
                                     // And for function arguments, `def_arg`.
-                                    DefArg(pattern.id, is_mutable)
+                                    DefArg(pattern.id, binding_mode)
                                 }
                             };
 
@@ -5361,7 +5352,7 @@ fn enforce_default_binding_mode(&mut self,
                                         pat_binding_mode: BindingMode,
                                         descr: &str) {
         match pat_binding_mode {
-            BindInfer => {}
+            BindByValue(_) => {}
             BindByRef(*) => {
                 self.resolve_error(
                     pat.span,
index 6bb41929db1d1a618451b6280a7a51a9b8b9f2ed..a36d938052a9175b7b2736b29218248fe2da30ae 100644 (file)
@@ -1842,7 +1842,7 @@ fn create_bindings_map(bcx: @mut Block, pat: @ast::Pat) -> BindingsMap {
         let llmatch;
         let trmode;
         match bm {
-            ast::BindInfer => {
+            ast::BindByValue(_) => {
                 // in this case, the final type of the variable will be T,
                 // but during matching we need to store a *T as explained
                 // above
@@ -2130,7 +2130,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
                     bcx, pat.id, path, binding_mode,
                     |bcx, variable_ty, llvariable_val| {
                         match pat_binding_mode {
-                            ast::BindInfer => {
+                            ast::BindByValue(_) => {
                                 // By value binding: move the value that `val`
                                 // points at into the binding's stack slot.
                                 let datum = Datum {val: val,
@@ -2241,7 +2241,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
 
 fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Path> {
     match pat.node {
-        ast::PatIdent(ast::BindInfer, ref path, None) => {
+        ast::PatIdent(ast::BindByValue(_), ref path, None) => {
             Some(path)
         }
         _ => {
index f00fa3e70e1bf808cac444406550475b92865548..47c1cf0064d552855d8d628f9e45f51b4f066b4b 100644 (file)
@@ -2100,7 +2100,6 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
     // Translate variant arguments to function arguments.
     let fn_args = do args.map |varg| {
         ast::arg {
-            is_mutbl: false,
             ty: (*varg.ty()).clone(),
             pat: ast_util::ident_to_pat(
                 ccx.tcx.sess.next_node_id(),
index 25048d888fa8c27da49de652d99e9edbd7b0e9c2..93c3d94f5dc69b7a661d47e4b1f448d3fac4f137 100644 (file)
@@ -476,7 +476,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::Pat, expected: ty::t) {
             demand::eqtype(fcx, pat.span, region_ty, typ);
           }
           // otherwise the type of x is the expected type T
-          ast::BindInfer => {
+          ast::BindByValue(_) => {
             demand::eqtype(fcx, pat.span, expected, typ);
           }
         }
index 372f1950c1de0047979beff35f0f4eb80999cb83..6647c4c811ec36386f3d1ec58d7a5f4e7c2d908f 100644 (file)
@@ -232,8 +232,8 @@ pub enum Def {
     DefMod(DefId),
     DefForeignMod(DefId),
     DefStatic(DefId, bool /* is_mutbl */),
-    DefArg(NodeId, bool /* is_mutbl */),
-    DefLocal(NodeId, bool /* is_mutbl */),
+    DefArg(NodeId, BindingMode),
+    DefLocal(NodeId, BindingMode),
     DefVariant(DefId /* enum */, DefId /* variant */, bool /* is_structure */),
     DefTy(DefId),
     DefTrait(DefId),
@@ -324,7 +324,7 @@ pub struct FieldPat {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum BindingMode {
     BindByRef(Mutability),
-    BindInfer
+    BindByValue(Mutability),
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
@@ -445,7 +445,6 @@ pub enum Stmt_ {
 // a refinement on pat.
 #[deriving(Eq, Encodable, Decodable,IterBytes)]
 pub struct Local {
-    is_mutbl: bool,
     ty: Ty,
     pat: @Pat,
     init: Option<@Expr>,
@@ -880,7 +879,6 @@ pub struct inline_asm {
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct arg {
-    is_mutbl: bool,
     ty: Ty,
     pat: @Pat,
     id: NodeId,
index 456d344b838c5baf65ea05744de32202764e452a..3ec87dbdd26fba67871318acdb821c5071b9e8b7 100644 (file)
@@ -234,7 +234,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
 
 pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> @Pat {
     @ast::Pat { id: id,
-                node: PatIdent(BindInfer, ident_to_path(s, i), None),
+                node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None),
                 span: s }
 }
 
index 78cdc3f585ba00449564474631912a776751316e..4c3ab840b440f314d2ad034431cd8ad283914795 100644 (file)
@@ -399,9 +399,12 @@ fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt {
     }
 
     fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt {
-        let pat = self.pat_ident(sp, ident);
+        let pat = if mutbl {
+            self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
+        } else {
+            self.pat_ident(sp, ident)
+        };
         let local = @ast::Local {
-            is_mutbl: mutbl,
             ty: self.ty_infer(sp),
             pat: pat,
             init: Some(ex),
@@ -419,9 +422,12 @@ fn stmt_let_typed(&self,
                       typ: ast::Ty,
                       ex: @ast::Expr)
                       -> @ast::Stmt {
-        let pat = self.pat_ident(sp, ident);
+        let pat = if mutbl {
+            self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
+        } else {
+            self.pat_ident(sp, ident)
+        };
         let local = @ast::Local {
-            is_mutbl: mutbl,
             ty: typ,
             pat: pat,
             init: Some(ex),
@@ -624,7 +630,7 @@ fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat {
         self.pat(span, ast::PatLit(expr))
     }
     fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat {
-        self.pat_ident_binding_mode(span, ident, ast::BindInfer)
+        self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable))
     }
 
     fn pat_ident_binding_mode(&self,
@@ -710,7 +716,6 @@ fn lambda_stmts_1(&self, span: Span, stmts: ~[@ast::Stmt], ident: ast::Ident) ->
     fn arg(&self, span: Span, ident: ast::Ident, ty: ast::Ty) -> ast::arg {
         let arg_pat = self.pat_ident(span, ident);
         ast::arg {
-            is_mutbl: false,
             ty: ty,
             pat: arg_pat,
             id: ast::DUMMY_NODE_ID
index c31c609d4e74afd0001a3279f7682db9c46a31aa..82a779546fcea0020bf5a9dadd6585bdccbea6d6 100644 (file)
@@ -922,7 +922,7 @@ fn create_struct_pattern(cx: @ExtCtxt,
     if struct_def.fields.is_empty() {
         return (
             cx.pat_ident_binding_mode(
-                span, struct_ident, ast::BindInfer),
+                span, struct_ident, ast::BindByValue(ast::MutImmutable)),
             ~[]);
     }
 
@@ -985,7 +985,7 @@ fn create_enum_variant_pattern(cx: @ExtCtxt,
         ast::tuple_variant_kind(ref variant_args) => {
             if variant_args.is_empty() {
                 return (cx.pat_ident_binding_mode(
-                    span, variant_ident, ast::BindInfer), ~[]);
+                    span, variant_ident, ast::BindByValue(ast::MutImmutable)), ~[]);
             }
 
             let matching_path = cx.path_ident(span, variant_ident);
index 99bcb36eedbf567af2e01f77a352a493f7c1b5d0..9526357f9ae8e7bc952d2ec60f2cd139e342f33b 100644 (file)
@@ -551,13 +551,13 @@ fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
             let pending_renames = block_info.pending_renames;
 
             // take it apart:
-            let @Local{is_mutbl:is_mutbl,
-                       ty:_,
-                       pat:pat,
-                       init:init,
-                       id:id,
-                       span:span
-                      } = *local;
+            let @Local {
+                ty: _,
+                pat: pat,
+                init: init,
+                id: id,
+                span: span
+            } = *local;
             // types can't be copied automatically because of the owned ptr in ty_tup...
             let ty = local.ty.clone();
             // expand the pat (it might contain exprs... #:(o)>
@@ -585,7 +585,6 @@ fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
             let new_init_opt = init.map(|e| fld.fold_expr(e));
             let rewritten_local =
                 @Local {
-                    is_mutbl: is_mutbl,
                     ty: ty,
                     pat: rewritten_pat,
                     init: new_init_opt,
index 37bc00d5827b9f252cb9d7633398308a8763118e..e9ecb95c54530038ea2fac1ea76a7f437ed21dba 100644 (file)
@@ -356,7 +356,6 @@ fn fold_path(&self, p: &Path) -> Path {
 
     fn fold_local(&self, l: @Local) -> @Local {
         @Local {
-            is_mutbl: l.is_mutbl,
             ty: self.fold_ty(&l.ty),
             pat: self.fold_pat(l.pat),
             init: l.init.map(|e| self.fold_expr(e)),
@@ -426,7 +425,6 @@ fn fold_attribute_<T:ast_fold>(at: Attribute, fld: &T) -> Attribute {
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_<T:ast_fold>(a: &arg, fld: &T) -> arg {
     ast::arg {
-        is_mutbl: a.is_mutbl,
         ty: fld.fold_ty(&a.ty),
         pat: fld.fold_pat(a.pat),
         id: fld.new_id(a.id),
index fad9eab75420042877630cfcd5ff59375e277992..0de571978a0e42b64e8f4931732490b0ec1047d7 100644 (file)
@@ -639,7 +639,7 @@ fn parser_done(p: Parser){
         assert_eq!(parser.parse_pat(),
                    @ast::Pat{id: ast::DUMMY_NODE_ID,
                              node: ast::PatIdent(
-                                ast::BindInfer,
+                                ast::BindByValue(ast::MutImmutable),
                                 ast::Path {
                                     span:sp(0,1),
                                     global:false,
@@ -666,7 +666,6 @@ fn parser_done(p: Parser){
                             id: ast::DUMMY_NODE_ID,
                             node: ast::item_fn(ast::fn_decl{
                                 inputs: ~[ast::arg{
-                                    is_mutbl: false,
                                     ty: ast::Ty{id: ast::DUMMY_NODE_ID,
                                                 node: ast::ty_path(ast::Path{
                                         span:sp(10,13),
@@ -685,7 +684,7 @@ fn parser_done(p: Parser){
                                     pat: @ast::Pat {
                                         id: ast::DUMMY_NODE_ID,
                                         node: ast::PatIdent(
-                                            ast::BindInfer,
+                                            ast::BindByValue(ast::MutImmutable),
                                             ast::Path {
                                                 span:sp(6,7),
                                                 global:false,
index 605e259cf0c2b2e89e18cada2eecd75b9b436296..d78c6189212dbd9a48ace618891cc60a0dda984c 100644 (file)
@@ -17,7 +17,7 @@
 use ast::{TyBareFn, TyClosure};
 use ast::{RegionTyParamBound, TraitTyParamBound};
 use ast::{provided, public, purity};
-use ast::{_mod, BiAdd, arg, Arm, Attribute, BindByRef, BindInfer};
+use ast::{_mod, BiAdd, arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
 use ast::{BlockCheckMode, UnBox};
 use ast::{Crate, CrateConfig, Decl, DeclItem};
@@ -1193,6 +1193,7 @@ pub fn is_named_argument(&self) -> bool {
                     1
                 }
             },
+            _ if token::is_keyword(keywords::Mut, self.token) => 1,
             _ => 0
         };
 
@@ -1210,16 +1211,11 @@ pub fn is_named_argument(&self) -> bool {
     // This version of parse arg doesn't necessarily require
     // identifier names.
     pub fn parse_arg_general(&self, require_name: bool) -> arg {
-        let is_mutbl = self.eat_keyword(keywords::Mut);
         let pat = if require_name || self.is_named_argument() {
             debug!("parse_arg_general parse_pat (require_name:{:?})",
                    require_name);
             let pat = self.parse_pat();
 
-            if is_mutbl && !ast_util::pat_is_ident(pat) {
-                self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
-            }
-
             self.expect(&token::COLON);
             pat
         } else {
@@ -1232,7 +1228,6 @@ pub fn parse_arg_general(&self, require_name: bool) -> arg {
         let t = self.parse_ty(false);
 
         ast::arg {
-            is_mutbl: is_mutbl,
             ty: t,
             pat: pat,
             id: ast::DUMMY_NODE_ID,
@@ -1246,7 +1241,6 @@ pub fn parse_arg(&self) -> arg {
 
     // parse an argument in a lambda header e.g. |arg, arg|
     pub fn parse_fn_block_arg(&self) -> arg {
-        let is_mutbl = self.eat_keyword(keywords::Mut);
         let pat = self.parse_pat();
         let t = if self.eat(&token::COLON) {
             self.parse_ty(false)
@@ -1258,7 +1252,6 @@ pub fn parse_fn_block_arg(&self) -> arg {
             }
         };
         ast::arg {
-            is_mutbl: is_mutbl,
             ty: t,
             pat: pat,
             id: ast::DUMMY_NODE_ID
@@ -2681,7 +2674,7 @@ fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) {
             } else {
                 subpat = @ast::Pat {
                     id: ast::DUMMY_NODE_ID,
-                    node: PatIdent(BindInfer, fieldpath, None),
+                    node: PatIdent(BindByValue(MutImmutable), fieldpath, None),
                     span: *self.last_span
                 };
             }
@@ -2863,6 +2856,8 @@ pub fn parse_pat(&self) -> @Pat {
             } else {
                 pat = PatLit(val);
             }
+        } else if self.eat_keyword(keywords::Mut) {
+            pat = self.parse_pat_ident(BindByValue(MutMutable));
         } else if self.eat_keyword(keywords::Ref) {
             // parse ref pat
             let mutbl = self.parse_mutability();
@@ -2891,7 +2886,7 @@ pub fn parse_pat(&self) -> @Pat {
                     // or just foo
                     sub = None;
                 }
-                pat = PatIdent(BindInfer, name, sub);
+                pat = PatIdent(BindByValue(MutImmutable), name, sub);
             } else {
                 // parse an enum pat
                 let enum_path = self.parse_path(LifetimeAndTypesWithColons)
@@ -2935,7 +2930,7 @@ pub fn parse_pat(&self) -> @Pat {
                                   // it could still be either an enum
                                   // or an identifier pattern, resolve
                                   // will sort it out:
-                                  pat = PatIdent(BindInfer,
+                                  pat = PatIdent(BindByValue(MutImmutable),
                                                   enum_path,
                                                   None);
                               } else {
@@ -2989,14 +2984,10 @@ fn parse_pat_ident(&self,
     }
 
     // parse a local variable declaration
-    fn parse_local(&self, is_mutbl: bool) -> @Local {
+    fn parse_local(&self) -> @Local {
         let lo = self.span.lo;
         let pat = self.parse_pat();
 
-        if is_mutbl && !ast_util::pat_is_ident(pat) {
-            self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
-        }
-
         let mut ty = Ty {
             id: ast::DUMMY_NODE_ID,
             node: ty_infer,
@@ -3005,7 +2996,6 @@ fn parse_local(&self, is_mutbl: bool) -> @Local {
         if self.eat(&token::COLON) { ty = self.parse_ty(false); }
         let init = self.parse_initializer();
         @ast::Local {
-            is_mutbl: is_mutbl,
             ty: ty,
             pat: pat,
             init: init,
@@ -3016,11 +3006,10 @@ fn parse_local(&self, is_mutbl: bool) -> @Local {
 
     // parse a "let" stmt
     fn parse_let(&self) -> @Decl {
-        let is_mutbl = self.eat_keyword(keywords::Mut);
         let lo = self.span.lo;
-        let local = self.parse_local(is_mutbl);
+        let local = self.parse_local();
         while self.eat(&token::COMMA) {
-            let _ = self.parse_local(is_mutbl);
+            let _ = self.parse_local();
             self.obsolete(*self.span, ObsoleteMultipleLocalDecl);
         }
         return @spanned(lo, self.last_span.hi, DeclLocal(local));
index 400ff804485239d79070b39826f30169eee8f2a4..121934119107e56e217fbbfeeab63c40886e75b5 100644 (file)
@@ -1476,10 +1476,6 @@ pub fn print_decl(s: @ps, decl: &ast::Decl) {
         ibox(s, indent_unit);
         word_nbsp(s, "let");
 
-        if loc.is_mutbl {
-            word_nbsp(s, "mut");
-        }
-
         fn print_local(s: @ps, loc: &ast::Local) {
             ibox(s, indent_unit);
             print_local_decl(s, loc);
@@ -1589,7 +1585,10 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
                   word_nbsp(s, "ref");
                   print_mutability(s, mutbl);
               }
-              ast::BindInfer => {}
+              ast::BindByValue(ast::MutImmutable) => {}
+              ast::BindByValue(ast::MutMutable) => {
+                  word_nbsp(s, "mut");
+              }
           }
           print_path(s, path, true);
           match sub {
@@ -1932,9 +1931,6 @@ pub fn print_mt(s: @ps, mt: &ast::mt) {
 
 pub fn print_arg(s: @ps, input: &ast::arg) {
     ibox(s, indent_unit);
-    if input.is_mutbl {
-        word_space(s, "mut");
-    }
     match input.ty.node {
       ast::ty_infer => print_pat(s, input.pat),
       _ => {