diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-06-04 21:43:41 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-06-04 21:45:42 -0700 |
| commit | 8114d0e9505b44856b822dd587293fd7895320e4 (patch) | |
| tree | 1e738ee1a533e43733225d9a66b065fb550b6dc7 /src/libsyntax | |
| parent | 16086ecff7edda82b114a72948762d59095f6fb4 (diff) | |
| download | rust-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.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/mod.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 69 | ||||
| -rw-r--r-- | src/libsyntax/parse/comments.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/parse/obsolete.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 21 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
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) } } |
