about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-11-07 19:25:39 -0800
committerBrian Anderson <banderson@mozilla.com>2013-11-18 16:19:48 -0800
commit85f107d8cba0560e1edce8ad7158024f2489ca3b (patch)
treec6e490a3a1d1bb9f806fbc607a54b4fc05502c47 /src/libsyntax
parent35e6c0252422b178cc3b21f7f1510c80bcd064c8 (diff)
Use '..' as slice wildcard in vectors
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/obsolete.rs7
-rw-r--r--src/libsyntax/parse/parser.rs40
-rw-r--r--src/libsyntax/print/pprust.rs8
-rw-r--r--src/libsyntax/visit.rs2
7 files changed, 46 insertions, 15 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 88a8bbf7cf2..79cf52d8da7 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -337,6 +337,7 @@ pub enum BindingMode {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum Pat_ {
     PatWild,
+    PatWildMulti,
     // A pat_ident may either be a new bound variable,
     // or a nullary enum (in which case the second field
     // is None).
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index ccae25dc012..fb50a890c43 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -657,7 +657,7 @@ pub fn walk_pat(pat: @Pat, it: &fn(@Pat) -> bool) -> bool {
                 slice.iter().advance(|&p| walk_pat(p, |p| it(p))) &&
                 after.iter().advance(|&p| walk_pat(p, |p| it(p)))
         }
-        PatWild | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
+        PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
         PatEnum(_, _) => {
             true
         }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index ea0ab95a451..bd99f58cde9 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -174,6 +174,7 @@ pub trait ast_fold {
     fn fold_pat(&self, p: @Pat) -> @Pat {
         let node = match p.node {
             PatWild => PatWild,
+            PatWildMulti => PatWildMulti,
             PatIdent(binding_mode, ref pth, ref sub) => {
                 PatIdent(binding_mode,
                          self.fold_path(pth),
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 8fb96a3e07a..2af6d141aa1 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -40,7 +40,8 @@ pub enum ObsoleteSyntax {
     ObsoleteEmptyImpl,
     ObsoleteLoopAsContinue,
     ObsoleteEnumWildcard,
-    ObsoleteStructWildcard
+    ObsoleteStructWildcard,
+    ObsoleteVecDotDotWildcard
 }
 
 impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -123,6 +124,10 @@ impl ParserObsoleteMethods for Parser {
                 "struct wildcard",
                 "use `..` instead of `_` for matching trailing struct fields"
             ),
+            ObsoleteVecDotDotWildcard => (
+                "vec slice wildcard",
+                "use `..` instead of `.._` for matching slices"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ea861305d9f..1b2e18f3ca5 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -43,7 +43,7 @@ use ast::{MutImmutable, MutMutable, mac_, mac_invoc_tt, matcher, match_nontermin
 use ast::{match_seq, match_tok, method, mt, BiMul, Mutability};
 use ast::{named_field, UnNeg, noreturn, UnNot, Pat, PatBox, PatEnum};
 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
-use ast::{PatTup, PatUniq, PatWild, private};
+use ast::{PatTup, PatUniq, PatWild, PatWildMulti, private};
 use ast::{BiRem, required};
 use ast::{ret_style, return_val, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, struct_def, struct_field};
@@ -2724,17 +2724,35 @@ impl Parser {
                 }
             }
 
-            let subpat = self.parse_pat();
             if is_slice {
-                match subpat {
-                    @ast::Pat { node: PatWild, _ } => (),
-                    @ast::Pat { node: PatIdent(_, _, _), _ } => (),
-                    @ast::Pat { span, _ } => self.span_fatal(
-                        span, "expected an identifier or `_`"
-                    )
+                if *self.token == token::COMMA || *self.token == token::RBRACKET {
+                    slice = Some(@ast::Pat {
+                        id: ast::DUMMY_NODE_ID,
+                        node: PatWildMulti,
+                        span: *self.span,
+                    })
+                } else {
+                    let subpat = self.parse_pat();
+                    match subpat {
+                        @ast::Pat { id, node: PatWild, span } => {
+                            // NOTE #5830 activate after snapshot
+                            // self.obsolete(*self.span, ObsoleteVecDotDotWildcard);
+                            slice = Some(@ast::Pat {
+                                id: id,
+                                node: PatWildMulti,
+                                span: span
+                            })
+                        },
+                        @ast::Pat { node: PatIdent(_, _, _), _ } => {
+                            slice = Some(subpat);
+                        }
+                        @ast::Pat { span, _ } => self.span_fatal(
+                            span, "expected an identifier or nothing"
+                        )
+                    }
                 }
-                slice = Some(subpat);
             } else {
+                let subpat = self.parse_pat();
                 if before_slice {
                     before.push(subpat);
                 } else {
@@ -2757,7 +2775,7 @@ impl Parser {
 
             etc = *self.token == token::UNDERSCORE || *self.token == token::DOTDOT;
             if *self.token == token::UNDERSCORE {
-                // FIXME #5830 activate after snapshot
+                // NOTE #5830 activate after snapshot
                 // self.obsolete(*self.span, ObsoleteStructWildcard);
             }
             if etc {
@@ -3031,7 +3049,7 @@ impl Parser {
                                 // This is a "top constructor only" pat
                                 self.bump();
                                 if is_star {
-                                    // FIXME #5830 activate after snapshot
+                                    // NOTE #5830 activate after snapshot
                                     // self.obsolete(*self.span, ObsoleteEnumWildcard);
                                 }
                                 self.bump();
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 9c4803474d9..68af73d4a01 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1613,6 +1613,7 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
      is that it doesn't matter */
     match pat.node {
       ast::PatWild => word(s.s, "_"),
+      ast::PatWildMulti => word(s.s, ".."),
       ast::PatIdent(binding_mode, ref path, sub) => {
           match binding_mode {
               ast::BindByRef(mutbl) => {
@@ -1701,7 +1702,12 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
         }
         for &p in slice.iter() {
             if !before.is_empty() { word_space(s, ","); }
-            word(s.s, "..");
+            match p {
+                @ast::Pat { node: ast::PatWildMulti, _ } => {
+                    // this case is handled by print_pat
+                }
+                _ => word(s.s, ".."),
+            }
             print_pat(s, p);
             if !after.is_empty() { word_space(s, ","); }
         }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a195bfb7717..aa712cae502 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -375,7 +375,7 @@ pub fn walk_pat<E:Clone, V:Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E) {
             visitor.visit_expr(lower_bound, env.clone());
             visitor.visit_expr(upper_bound, env)
         }
-        PatWild => (),
+        PatWild | PatWildMulti => (),
         PatVec(ref prepattern, ref slice_pattern, ref postpatterns) => {
             for prepattern in prepattern.iter() {
                 visitor.visit_pat(*prepattern, env.clone())