about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorLuqman Aden <laden@csclub.uwaterloo.ca>2013-10-20 08:31:23 -0400
committerLuqman Aden <laden@csclub.uwaterloo.ca>2013-10-25 01:21:07 -0400
commit12308db3d23fe59b7ccfed6c535896ac6fdb5abe (patch)
tree0ee8744bc3fa89748369deb97429df97a83ef056 /src/libsyntax
parentc16a95c587bb5ff5f06894657a1d7aafc69a2084 (diff)
downloadrust-12308db3d23fe59b7ccfed6c535896ac6fdb5abe.tar.gz
rust-12308db3d23fe59b7ccfed6c535896ac6fdb5abe.zip
libsyntax/librustc: Allow mut qualifier in patterns.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs8
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/ext/build.rs17
-rw-r--r--src/libsyntax/ext/deriving/generic.rs4
-rw-r--r--src/libsyntax/ext/expand.rs15
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/parse/mod.rs5
-rw-r--r--src/libsyntax/parse/parser.rs31
-rw-r--r--src/libsyntax/print/pprust.rs12
9 files changed, 40 insertions, 56 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 372f1950c1d..6647c4c811e 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -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,
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 456d344b838..3ec87dbdd26 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -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 }
 }
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 78cdc3f585b..4c3ab840b44 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -399,9 +399,12 @@ impl AstBuilder for @ExtCtxt {
     }
 
     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 @@ impl AstBuilder for @ExtCtxt {
                       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 @@ impl AstBuilder for @ExtCtxt {
         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 @@ impl AstBuilder for @ExtCtxt {
     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
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index c31c609d4e7..82a779546fc 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -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);
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 99bcb36eedb..9526357f9ae 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -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,
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 37bc00d5827..e9ecb95c545 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -356,7 +356,6 @@ pub trait ast_fold {
 
     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),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index fad9eab7542..0de571978a0 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -639,7 +639,7 @@ mod test {
         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 @@ mod test {
                             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 @@ mod test {
                                     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,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 605e259cf0c..d78c6189212 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -17,7 +17,7 @@ use ast::{CallSugar, NoSugar, DoSugar};
 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 @@ impl Parser {
                     1
                 }
             },
+            _ if token::is_keyword(keywords::Mut, self.token) => 1,
             _ => 0
         };
 
@@ -1210,16 +1211,11 @@ impl Parser {
     // 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 @@ impl Parser {
         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 @@ impl Parser {
 
     // 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 @@ impl Parser {
             }
         };
         ast::arg {
-            is_mutbl: is_mutbl,
             ty: t,
             pat: pat,
             id: ast::DUMMY_NODE_ID
@@ -2681,7 +2674,7 @@ impl Parser {
             } 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 @@ impl Parser {
             } 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 @@ impl Parser {
                     // 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 @@ impl Parser {
                                   // 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 @@ impl Parser {
     }
 
     // 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 @@ impl Parser {
         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 @@ impl Parser {
 
     // 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));
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 400ff804485..12193411910 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -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),
       _ => {