about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-06-04 21:43:41 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-06-04 21:45:42 -0700
commit8114d0e9505b44856b822dd587293fd7895320e4 (patch)
tree1e738ee1a533e43733225d9a66b065fb550b6dc7 /src/libsyntax
parent16086ecff7edda82b114a72948762d59095f6fb4 (diff)
downloadrust-8114d0e9505b44856b822dd587293fd7895320e4.tar.gz
rust-8114d0e9505b44856b822dd587293fd7895320e4.zip
librustc: Disallow multiple patterns from appearing in a "let" declaration.
You can still initialize multiple variables at once with "let (x, y) = (1, 2)".
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs5
-rw-r--r--src/libsyntax/ast_util.rs3
-rw-r--r--src/libsyntax/ext/build.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic.rs9
-rw-r--r--src/libsyntax/ext/deriving/mod.rs7
-rw-r--r--src/libsyntax/ext/expand.rs22
-rw-r--r--src/libsyntax/fold.rs69
-rw-r--r--src/libsyntax/parse/comments.rs3
-rw-r--r--src/libsyntax/parse/lexer.rs8
-rw-r--r--src/libsyntax/parse/obsolete.rs6
-rw-r--r--src/libsyntax/parse/parser.rs21
-rw-r--r--src/libsyntax/print/pprust.rs9
-rw-r--r--src/libsyntax/visit.rs6
13 files changed, 111 insertions, 59 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f694e37d42f..625bcd4ec9c 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -413,7 +413,10 @@ pub type local = spanned<local_>;
 pub type decl = spanned<decl_>;
 
 #[deriving(Eq, Encodable, Decodable)]
-pub enum decl_ { decl_local(~[@local]), decl_item(@item), }
+pub enum decl_ {
+    decl_local(@local),
+    decl_item(@item),
+}
 
 #[deriving(Eq, Encodable, Decodable)]
 pub struct arm {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 95dce88d450..e2b8677d5a4 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -279,7 +279,8 @@ pub fn trait_method_to_ty_method(method: &trait_method) -> ty_method {
 
 pub fn split_trait_methods(trait_methods: &[trait_method])
     -> (~[ty_method], ~[@method]) {
-    let mut reqd = ~[], provd = ~[];
+    let mut reqd = ~[];
+    let mut provd = ~[];
     for trait_methods.each |trt_method| {
         match *trt_method {
           required(ref tm) => reqd.push(copy *tm),
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index c2fa888995a..324b909fbb0 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -385,7 +385,7 @@ impl AstBuilder for @ExtCtxt {
                                 init: Some(ex),
                                 id: self.next_id(),
                             });
-        let decl = respan(sp, ast::decl_local(~[local]));
+        let decl = respan(sp, ast::decl_local(local));
         @respan(sp, ast::stmt_decl(@decl, self.next_id()))
     }
 
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index d4b3488cc4f..2e6cac1876b 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -416,7 +416,9 @@ impl<'self> MethodDef<'self> {
                              type_ident: ident, generics: &Generics)
         -> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) {
 
-        let mut self_args = ~[], nonself_args = ~[], arg_tys = ~[];
+        let mut self_args = ~[];
+        let mut nonself_args = ~[];
+        let mut arg_tys = ~[];
         let mut nonstatic = false;
 
         let ast_explicit_self = match self.explicit_self {
@@ -522,8 +524,9 @@ impl<'self> MethodDef<'self> {
                                  nonself_args: &[@expr])
         -> @expr {
 
-        let mut raw_fields = ~[], // ~[[fields of self], [fields of next Self arg], [etc]]
-                patterns = ~[];
+        let mut raw_fields = ~[]; // ~[[fields of self],
+                                 // [fields of next Self arg], [etc]]
+        let mut patterns = ~[];
         for uint::range(0, self_args.len()) |i| {
             let (pat, ident_expr) = create_struct_pattern(cx, span,
                                                           type_ident, struct_def,
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 796ccd304ff..13c552388e1 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -264,8 +264,8 @@ pub fn create_struct_pattern(cx: @ExtCtxt,
 
     let matching_path = cx.path(span, ~[ struct_ident ]);
 
-    let mut paths = ~[], ident_expr = ~[];
-
+    let mut paths = ~[];
+    let mut ident_expr = ~[];
     let mut struct_type = Unknown;
 
     for struct_def.fields.eachi |i, struct_field| {
@@ -326,7 +326,8 @@ pub fn create_enum_variant_pattern(cx: @ExtCtxt,
 
             let matching_path = cx.path_ident(span, variant_ident);
 
-            let mut paths = ~[], ident_expr = ~[];
+            let mut paths = ~[];
+            let mut ident_expr = ~[];
             for uint::range(0, variant_args.len()) |i| {
                 let path = cx.path_ident(span,
                                          cx.ident_of(fmt!("%s_%u", prefix, i)));
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 89ed9b7294d..45b9be07a98 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -302,8 +302,9 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
                    s: &stmt_,
                    sp: span,
                    fld: @ast_fold,
-                   orig: @fn(&stmt_, span, @ast_fold) -> (stmt_, span))
-                -> (stmt_, span) {
+                   orig: @fn(&stmt_, span, @ast_fold)
+                             -> (Option<stmt_>, span))
+                -> (Option<stmt_>, span) {
     let (mac, pth, tts, semi) = match *s {
         stmt_mac(ref mac, semi) => {
             match mac.node {
@@ -342,8 +343,17 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
             };
 
             //keep going, outside-in
-            let fully_expanded = copy fld.fold_stmt(expanded).node;
-            cx.bt_pop();
+            let fully_expanded = match fld.fold_stmt(expanded) {
+                Some(stmt) => {
+                    let fully_expanded = &stmt.node;
+                    cx.bt_pop();
+                    copy *fully_expanded
+                }
+                None => {
+                    cx.span_fatal(pth.span,
+                                  "macro didn't expand to a statement")
+                }
+            };
 
             (fully_expanded, sp)
         }
@@ -355,8 +365,8 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
     };
 
     (match fully_expanded {
-        stmt_expr(e, stmt_id) if semi => stmt_semi(e, stmt_id),
-        _ => { fully_expanded } /* might already have a semi */
+        stmt_expr(e, stmt_id) if semi => Some(stmt_semi(e, stmt_id)),
+        _ => { Some(fully_expanded) } /* might already have a semi */
     }, sp)
 
 }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 5800254eaa4..d419ce6f188 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -26,10 +26,10 @@ pub trait ast_fold {
     fn fold_item_underscore(@self, &item_) -> item_;
     fn fold_method(@self, @method) -> @method;
     fn fold_block(@self, &blk) -> blk;
-    fn fold_stmt(@self, &stmt) -> @stmt;
+    fn fold_stmt(@self, &stmt) -> Option<@stmt>;
     fn fold_arm(@self, &arm) -> arm;
     fn fold_pat(@self, @pat) -> @pat;
-    fn fold_decl(@self, @decl) -> @decl;
+    fn fold_decl(@self, @decl) -> Option<@decl>;
     fn fold_expr(@self, @expr) -> @expr;
     fn fold_ty(@self, @Ty) -> @Ty;
     fn fold_mod(@self, &_mod) -> _mod;
@@ -55,10 +55,10 @@ pub struct AstFoldFns {
     fold_item_underscore: @fn(&item_, @ast_fold) -> item_,
     fold_method: @fn(@method, @ast_fold) -> @method,
     fold_block: @fn(&blk_, span, @ast_fold) -> (blk_, span),
-    fold_stmt: @fn(&stmt_, span, @ast_fold) -> (stmt_, span),
+    fold_stmt: @fn(&stmt_, span, @ast_fold) -> (Option<stmt_>, span),
     fold_arm: @fn(&arm, @ast_fold) -> arm,
     fold_pat: @fn(&pat_, span, @ast_fold) -> (pat_, span),
-    fold_decl: @fn(&decl_, span, @ast_fold) -> (decl_, span),
+    fold_decl: @fn(&decl_, span, @ast_fold) -> (Option<decl_>, span),
     fold_expr: @fn(&expr_, span, @ast_fold) -> (expr_, span),
     fold_ty: @fn(&ty_, span, @ast_fold) -> (ty_, span),
     fold_mod: @fn(&_mod, @ast_fold) -> _mod,
@@ -340,22 +340,39 @@ fn noop_fold_method(m: @method, fld: @ast_fold) -> @method {
 
 
 pub fn noop_fold_block(b: &blk_, fld: @ast_fold) -> blk_ {
+    let view_items = b.view_items.map(|x| fld.fold_view_item(*x));
+    let mut stmts = ~[];
+    for b.stmts.each |stmt| {
+        match fld.fold_stmt(*stmt) {
+            None => {}
+            Some(stmt) => stmts.push(stmt)
+        }
+    }
     ast::blk_ {
-        view_items: b.view_items.map(|x| fld.fold_view_item(*x)),
-        stmts: b.stmts.map(|x| fld.fold_stmt(*x)),
+        view_items: view_items,
+        stmts: stmts,
         expr: b.expr.map(|x| fld.fold_expr(*x)),
         id: fld.new_id(b.id),
         rules: b.rules,
     }
 }
 
-fn noop_fold_stmt(s: &stmt_, fld: @ast_fold) -> stmt_ {
+fn noop_fold_stmt(s: &stmt_, fld: @ast_fold) -> Option<stmt_> {
     let fold_mac = |x| fold_mac_(x, fld);
     match *s {
-        stmt_decl(d, nid) => stmt_decl(fld.fold_decl(d), fld.new_id(nid)),
-        stmt_expr(e, nid) => stmt_expr(fld.fold_expr(e), fld.new_id(nid)),
-        stmt_semi(e, nid) => stmt_semi(fld.fold_expr(e), fld.new_id(nid)),
-        stmt_mac(ref mac, semi) => stmt_mac(fold_mac(mac), semi)
+        stmt_decl(d, nid) => {
+            match fld.fold_decl(d) {
+                Some(d) => Some(stmt_decl(d, fld.new_id(nid))),
+                None => None,
+            }
+        }
+        stmt_expr(e, nid) => {
+            Some(stmt_expr(fld.fold_expr(e), fld.new_id(nid)))
+        }
+        stmt_semi(e, nid) => {
+            Some(stmt_semi(fld.fold_expr(e), fld.new_id(nid)))
+        }
+        stmt_mac(ref mac, semi) => Some(stmt_mac(fold_mac(mac), semi))
     }
 }
 
@@ -411,13 +428,13 @@ pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ {
     }
 }
 
-fn noop_fold_decl(d: &decl_, fld: @ast_fold) -> decl_ {
+fn noop_fold_decl(d: &decl_, fld: @ast_fold) -> Option<decl_> {
     match *d {
-        decl_local(ref ls) => decl_local(ls.map(|x| fld.fold_local(*x))),
+        decl_local(ref l) => Some(decl_local(fld.fold_local(*l))),
         decl_item(it) => {
             match fld.fold_item(it) {
-                Some(it_folded) => decl_item(it_folded),
-                None => decl_local(~[]),
+                Some(it_folded) => Some(decl_item(it_folded)),
+                None => None,
             }
         }
     }
@@ -738,10 +755,10 @@ pub fn default_ast_fold() -> ast_fold_fns {
         fold_item_underscore: noop_fold_item_underscore,
         fold_method: noop_fold_method,
         fold_block: wrap(noop_fold_block),
-        fold_stmt: wrap(noop_fold_stmt),
+        fold_stmt: |x, s, fld| (noop_fold_stmt(x, fld), s),
         fold_arm: noop_fold_arm,
         fold_pat: wrap(noop_fold_pat),
-        fold_decl: wrap(noop_fold_decl),
+        fold_decl: |x, s, fld| (noop_fold_decl(x, fld), s),
         fold_expr: wrap(noop_fold_expr),
         fold_ty: wrap(noop_fold_ty),
         fold_mod: noop_fold_mod,
@@ -799,9 +816,12 @@ impl ast_fold for AstFoldFns {
         let (n, s) = (self.fold_block)(&x.node, x.span, self as @ast_fold);
         spanned { node: n, span: (self.new_span)(s) }
     }
-    fn fold_stmt(@self, x: &stmt) -> @stmt {
-        let (n, s) = (self.fold_stmt)(&x.node, x.span, self as @ast_fold);
-        @spanned { node: n, span: (self.new_span)(s) }
+    fn fold_stmt(@self, x: &stmt) -> Option<@stmt> {
+        let (n_opt, s) = (self.fold_stmt)(&x.node, x.span, self as @ast_fold);
+        match n_opt {
+            Some(n) => Some(@spanned { node: n, span: (self.new_span)(s) }),
+            None => None,
+        }
     }
     fn fold_arm(@self, x: &arm) -> arm {
         (self.fold_arm)(x, self as @ast_fold)
@@ -814,9 +834,12 @@ impl ast_fold for AstFoldFns {
             span: (self.new_span)(s),
         }
     }
-    fn fold_decl(@self, x: @decl) -> @decl {
-        let (n, s) = (self.fold_decl)(&x.node, x.span, self as @ast_fold);
-        @spanned { node: n, span: (self.new_span)(s) }
+    fn fold_decl(@self, x: @decl) -> Option<@decl> {
+        let (n_opt, s) = (self.fold_decl)(&x.node, x.span, self as @ast_fold);
+        match n_opt {
+            Some(n) => Some(@spanned { node: n, span: (self.new_span)(s) }),
+            None => None,
+        }
     }
     fn fold_expr(@self, x: @expr) -> @expr {
         let (n, s) = (self.fold_expr)(&x.node, x.span, self as @ast_fold);
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 001a693d1ae..2f166ae89ef 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -58,7 +58,8 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
 
     /// remove whitespace-only lines from the start/end of lines
     fn vertical_trim(lines: ~[~str]) -> ~[~str] {
-        let mut i = 0u, j = lines.len();
+        let mut i = 0u;
+        let mut j = lines.len();
         while i < j && lines[i].trim().is_empty() {
             i += 1u;
         }
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 0e04e719020..0eb933e6c3a 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -387,7 +387,10 @@ fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str {
 }
 
 fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
-    let mut num_str, base = 10u, c = c, n = nextch(rdr);
+    let mut num_str;
+    let mut base = 10u;
+    let mut c = c;
+    let mut n = nextch(rdr);
     if c == '0' && n == 'x' {
         bump(rdr);
         bump(rdr);
@@ -510,7 +513,8 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
 }
 
 fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char {
-    let mut accum_int = 0, i = n_hex_digits;
+    let mut accum_int = 0;
+    let mut i = n_hex_digits;
     while i != 0u {
         let n = rdr.curr;
         bump(rdr);
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index f37b430b480..61b7f1403e6 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -64,6 +64,7 @@ pub enum ObsoleteSyntax {
     ObsoleteConstItem,
     ObsoleteFixedLengthVectorType,
     ObsoleteNamedExternModule,
+    ObsoleteMultipleLocalDecl,
 }
 
 impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -224,6 +225,11 @@ impl Parser {
                 "instead of `extern mod foo { ... }`, write `mod foo { \
                  extern { ... } }`"
             ),
+            ObsoleteMultipleLocalDecl => (
+                "declaration of multiple locals at once",
+                "instead of e.g. `let a = 1, b = 2`, write \
+                 `let (a, b) = (1, 2)`."
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index dd966815ad2..23e3f145398 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -84,7 +84,7 @@ use parse::obsolete::ObsoleteMode;
 use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer};
 use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod};
 use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType};
-use parse::obsolete::{ObsoleteNamedExternModule};
+use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl};
 use parse::token::{can_begin_expr, is_ident, is_ident_or_path};
 use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents, token_to_binop};
 use parse::token;
@@ -2573,11 +2573,12 @@ impl Parser {
     fn parse_let(&self) -> @decl {
         let is_mutbl = self.eat_keyword(keywords::Mut);
         let lo = self.span.lo;
-        let mut locals = ~[self.parse_local(is_mutbl)];
+        let mut local = self.parse_local(is_mutbl);
         while self.eat(&token::COMMA) {
-            locals.push(self.parse_local(is_mutbl));
+            let _ = self.parse_local(is_mutbl);
+            self.obsolete(*self.span, ObsoleteMultipleLocalDecl);
         }
-        return @spanned(lo, self.last_span.hi, decl_local(locals));
+        return @spanned(lo, self.last_span.hi, decl_local(local));
     }
 
     // parse a structure field
@@ -3840,15 +3841,18 @@ impl Parser {
     // parse the part of an "enum" decl following the '{'
     fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def {
         let mut variants = ~[];
-        let mut all_nullary = true, have_disr = false;
+        let mut all_nullary = true;
+        let mut have_disr = false;
         while *self.token != token::RBRACE {
             let variant_attrs = self.parse_outer_attributes();
             let vlo = self.span.lo;
 
             let vis = self.parse_visibility();
 
-            let ident, kind;
-            let mut args = ~[], disr_expr = None;
+            let ident;
+            let kind;
+            let mut args = ~[];
+            let mut disr_expr = None;
             ident = self.parse_ident();
             if self.eat(&token::LBRACE) {
                 // Parse a struct variant.
@@ -4352,7 +4356,8 @@ impl Parser {
     }
 
     fn is_view_item(&self) -> bool {
-        let tok, next_tok;
+        let tok;
+        let next_tok;
         if !self.is_keyword(keywords::Pub) && !self.is_keyword(keywords::Priv) {
             tok = copy *self.token;
             next_tok = self.look_ahead(1);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 7ab38a6ba5f..7a3eddbd573 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1444,14 +1444,12 @@ pub fn print_local_decl(s: @ps, loc: @ast::local) {
 pub fn print_decl(s: @ps, decl: @ast::decl) {
     maybe_print_comment(s, decl.span.lo);
     match decl.node {
-      ast::decl_local(ref locs) => {
+      ast::decl_local(ref loc) => {
         space_if_not_bol(s);
         ibox(s, indent_unit);
         word_nbsp(s, "let");
 
-        // if any are mut, all are mut
-        if locs.any(|l| l.node.is_mutbl) {
-            assert!(locs.all(|l| l.node.is_mutbl));
+        if loc.node.is_mutbl {
             word_nbsp(s, "mut");
         }
 
@@ -1468,7 +1466,8 @@ pub fn print_decl(s: @ps, decl: @ast::decl) {
               _ => ()
             }
         }
-        commasep(s, consistent, *locs, print_local);
+
+        print_local(s, *loc);
         end(s);
       }
       ast::decl_item(item) => print_item(s, item)
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 0cb22737a53..bf75efb805f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -430,11 +430,7 @@ pub fn visit_stmt<E>(s: @stmt, e: E, v: vt<E>) {
 
 pub fn visit_decl<E: Copy>(d: @decl, e: E, v: vt<E>) {
     match d.node {
-        decl_local(ref locs) => {
-            for locs.each |loc| {
-                (v.visit_local)(*loc, e, v)
-            }
-        },
+        decl_local(ref loc) => (v.visit_local)(*loc, e, v),
         decl_item(it) => (v.visit_item)(it, e, v)
     }
 }