Skip to content

Commit

Permalink
Use '..' as slice wildcard in vectors
Browse files Browse the repository at this point in the history
  • Loading branch information
brson committed Nov 19, 2013
1 parent 35e6c02 commit 85f107d
Show file tree
Hide file tree
Showing 17 changed files with 77 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/librustc/middle/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}

Expand Down
13 changes: 10 additions & 3 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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,
Expand All @@ -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, _)) => {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ impl mem_categorization_ctxt {
op(cmt, pat);

match pat.node {
ast::PatWild => {
ast::PatWild | ast::PatWildMulti => {
// _
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/pat_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
7 changes: 6 additions & 1 deletion src/libsyntax/parse/obsolete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ pub enum ObsoleteSyntax {
ObsoleteEmptyImpl,
ObsoleteLoopAsContinue,
ObsoleteEnumWildcard,
ObsoleteStructWildcard
ObsoleteStructWildcard,
ObsoleteVecDotDotWildcard
}

impl to_bytes::IterBytes for ObsoleteSyntax {
Expand Down Expand Up @@ -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);
Expand Down
40 changes: 29 additions & 11 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 7 additions & 1 deletion src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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, ","); }
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
18 changes: 12 additions & 6 deletions src/test/run-pass/ignore-all-the-things.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, .._] => { }
}
Expand Down

5 comments on commit 85f107d

@bors
Copy link
Contributor

@bors bors commented on 85f107d Nov 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at brson@85f107d

@bors
Copy link
Contributor

@bors bors commented on 85f107d Nov 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging brson/rust/ignore-patterns = 85f107d into auto

@bors
Copy link
Contributor

@bors bors commented on 85f107d Nov 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brson/rust/ignore-patterns = 85f107d merged ok, testing candidate = 7fc3e82

@bors
Copy link
Contributor

@bors bors commented on 85f107d Nov 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 85f107d Nov 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 7fc3e82

Please sign in to comment.