ast::PatEnum(_, None) |
ast::PatLit(*) |
ast::PatRange(*) |
- ast::PatWild => {
+ ast::PatWild | ast::PatWildMulti => {
self.add_node(pat.id, [pred])
}
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)),
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 }
@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,
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, _)) => {
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
op(cmt, pat);
match pat.node {
- ast::PatWild => {
+ ast::PatWild | ast::PatWildMulti => {
// _
}
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
}
}
// 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
}
pat.span,
format!("vector patterns are never irrefutable!"));
}
- ast::PatWild | ast::PatLit(_) | ast::PatRange(_, _) => ()
+ ast::PatWild | ast::PatWildMulti | ast::PatLit(_) | ast::PatRange(_, _) => ()
}
return bcx;
}
}
}
- ast::PatWild => {
+ ast::PatWild | ast::PatWildMulti => {
scope_map.insert(pat.id, scope_stack.last().scope_metadata);
}
let tcx = pcx.fcx.ccx.tcx;
match pat.node {
- ast::PatWild => {
+ ast::PatWild | ast::PatWildMulti => {
fcx.write_ty(pat.id, expected);
}
ast::PatLit(lt) => {
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);
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, \
#[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).
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
}
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),
ObsoleteEmptyImpl,
ObsoleteLoopAsContinue,
ObsoleteEnumWildcard,
- ObsoleteStructWildcard
+ ObsoleteStructWildcard,
+ ObsoleteVecDotDotWildcard
}
impl to_bytes::IterBytes for ObsoleteSyntax {
"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);
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};
}
}
- 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 {
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 {
// 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();
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) => {
}
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, ","); }
}
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())
//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, .._] => { }
}