about summary refs log tree commit diff
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
parent35e6c0252422b178cc3b21f7f1510c80bcd064c8 (diff)
downloadrust-85f107d8cba0560e1edce8ad7158024f2489ca3b.tar.gz
rust-85f107d8cba0560e1edce8ad7158024f2489ca3b.zip
Use '..' as slice wildcard in vectors
-rw-r--r--src/librustc/middle/cfg/construct.rs2
-rw-r--r--src/librustc/middle/check_match.rs13
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc/middle/pat_util.rs2
-rw-r--r--src/librustc/middle/trans/_match.rs4
-rw-r--r--src/librustc/middle/trans/debuginfo.rs2
-rw-r--r--src/librustc/middle/typeck/check/_match.rs2
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs2
-rw-r--r--src/librustdoc/clean.rs1
-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
-rw-r--r--src/test/run-pass/ignore-all-the-things.rs18
17 files changed, 77 insertions, 32 deletions
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index fce318f173e..e014f41edcd 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -97,7 +97,7 @@ impl CFGBuilder {
             ast::PatEnum(_, None) |
             ast::PatLit(*) |
             ast::PatRange(*) |
-            ast::PatWild => {
+            ast::PatWild | ast::PatWildMulti => {
                 self.add_node(pat.id, [pred])
             }
 
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 482ba43ae25..3885ebfc4b6 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -333,7 +333,7 @@ fn is_useful_specialized(cx: &MatchCheckCtxt,
 fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
     let pat = raw_pat(p);
     match pat.node {
-      PatWild => { None }
+      PatWild | PatWildMulti => { None }
       PatIdent(_, _, _) | PatEnum(_, _) => {
         match cx.tcx.def_map.find(&pat.id) {
           Some(&DefVariant(_, id, _)) => Some(variant(id)),
@@ -369,7 +369,7 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
 fn is_wild(cx: &MatchCheckCtxt, p: @Pat) -> bool {
     let pat = raw_pat(p);
     match pat.node {
-      PatWild => { true }
+      PatWild | PatWildMulti => { true }
       PatIdent(_, _, _) => {
         match cx.tcx.def_map.find(&pat.id) {
           Some(&DefVariant(_, _, _)) | Some(&DefStatic(*)) => { false }
@@ -532,6 +532,10 @@ fn wild() -> @Pat {
     @Pat {id: 0, node: PatWild, span: dummy_sp()}
 }
 
+fn wild_multi() -> @Pat {
+    @Pat {id: 0, node: PatWildMulti, span: dummy_sp()}
+}
+
 fn specialize(cx: &MatchCheckCtxt,
                   r: &[@Pat],
                   ctor_id: &ctor,
@@ -546,6 +550,9 @@ fn specialize(cx: &MatchCheckCtxt,
             PatWild => {
                 Some(vec::append(vec::from_elem(arity, wild()), r.tail()))
             }
+            PatWildMulti => {
+                Some(vec::append(vec::from_elem(arity, wild_multi()), r.tail()))
+            }
             PatIdent(_, _, _) => {
                 match cx.tcx.def_map.find(&pat_id) {
                     Some(&DefVariant(_, id, _)) => {
@@ -849,7 +856,7 @@ fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat) -> bool {
       PatIdent(_, _, Some(sub)) => {
         is_refutable(cx, sub)
       }
-      PatWild | PatIdent(_, _, None) => { false }
+      PatWild | PatWildMulti | PatIdent(_, _, None) => { false }
       PatLit(@Expr {node: ExprLit(@Spanned { node: lit_nil, _}), _}) => {
         // "()"
         false
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index bd2f69a1d03..d8f66419379 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -876,7 +876,7 @@ impl mem_categorization_ctxt {
         op(cmt, pat);
 
         match pat.node {
-          ast::PatWild => {
+          ast::PatWild | ast::PatWildMulti => {
             // _
           }
 
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index acdadacc083..878f0876918 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -65,7 +65,7 @@ pub fn pat_is_binding(dm: resolve::DefMap, pat: @Pat) -> bool {
 pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @Pat) -> bool {
     match pat.node {
         PatIdent(*) => pat_is_binding(dm, pat),
-        PatWild => true,
+        PatWild | PatWildMulti => true,
         _ => false
     }
 }
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 9dddf96e34d..b48260de766 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -545,7 +545,7 @@ fn enter_default<'r>(bcx: @mut Block,
     // Collect all of the matches that can match against anything.
     let matches = do enter_match(bcx, dm, m, col, val) |p| {
         match p.node {
-          ast::PatWild | ast::PatTup(_) => Some(~[]),
+          ast::PatWild | ast::PatWildMulti | ast::PatTup(_) => Some(~[]),
           ast::PatIdent(_, _, None) if pat_is_binding(dm, p) => Some(~[]),
           _ => None
         }
@@ -2234,7 +2234,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
                 pat.span,
                 format!("vector patterns are never irrefutable!"));
         }
-        ast::PatWild | ast::PatLit(_) | ast::PatRange(_, _) => ()
+        ast::PatWild | ast::PatWildMulti | ast::PatLit(_) | ast::PatRange(_, _) => ()
     }
     return bcx;
 }
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index c6a33864620..6c010e4f85b 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -2418,7 +2418,7 @@ fn populate_scope_map(cx: &mut CrateContext,
                 }
             }
 
-            ast::PatWild => {
+            ast::PatWild | ast::PatWildMulti => {
                 scope_map.insert(pat.id, scope_stack.last().scope_metadata);
             }
 
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 93c3d94f5dc..63f439e43e3 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -414,7 +414,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::Pat, expected: ty::t) {
     let tcx = pcx.fcx.ccx.tcx;
 
     match pat.node {
-      ast::PatWild => {
+      ast::PatWild | ast::PatWildMulti => {
         fcx.write_ty(pat.id, expected);
       }
       ast::PatLit(lt) => {
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index b21d36777c2..c3827037f15 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -1219,7 +1219,7 @@ pub mod guarantor {
                rcx.fcx.pat_to_str(pat), guarantor);
 
         match pat.node {
-            ast::PatWild => {}
+            ast::PatWild | ast::PatWildMulti => {}
             ast::PatIdent(ast::BindByRef(_), _, opt_p) => {
                 link(rcx, pat.span, pat.id, guarantor);
 
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index f48ad25712d..f0f2ca2db33 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -1137,6 +1137,7 @@ fn name_from_pat(p: &ast::Pat) -> ~str {
     use syntax::ast::*;
     match p.node {
         PatWild => ~"_",
+        PatWildMulti => ~"..",
         PatIdent(_, ref p, _) => path_to_str(p),
         PatEnum(ref p, _) => path_to_str(p),
         PatStruct(*) => fail!("tried to get argument name from pat_struct, \
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())
diff --git a/src/test/run-pass/ignore-all-the-things.rs b/src/test/run-pass/ignore-all-the-things.rs
index b71f139c684..b3b93c768d1 100644
--- a/src/test/run-pass/ignore-all-the-things.rs
+++ b/src/test/run-pass/ignore-all-the-things.rs
@@ -23,15 +23,21 @@ pub fn main() {
     //let (.., c, d) = (5, 5, 5, 5);
     let Bar{b: b, ..} = Bar{a: 5, b: 5, c: 5, d: 5};
     let Bar{b: b, _} = Bar{a: 5, b: 5, c: 5, d: 5};
-    /*match [5, 5, 5, 5] {
+    match [5, 5, 5, 5] {
+        [..] => { }
+    }
+    match [5, 5, 5, 5] {
         [a, ..] => { }
-    }*/
-    /*match [5, 5, 5, 5] {
+    }
+    match [5, 5, 5, 5] {
         [.., b] => { }
-    }*/
-    /*match [5, 5, 5, 5] {
+    }
+    match [5, 5, 5, 5] {
         [a, .., b] => { }
-    }*/
+    }
+    match [5, 5, 5] {
+        [.._] => { }
+    }
     match [5, 5, 5] {
         [a, .._] => { }
     }