Skip to content

Commit 7fc3e82

Browse files
committed
auto merge of #10366 : brson/rust/ignore-patterns, r=alexcrichton
This replaces `*` with `..` in enums, `_` with `..` in structs, and `.._` with `..` in vectors. It adds obsolete syntax warnings for the old forms but doesn't turn them on yet because we need a snapshot. #5830
2 parents 9062988 + 85f107d commit 7fc3e82

File tree

17 files changed

+138
-24
lines changed

17 files changed

+138
-24
lines changed

src/librustc/middle/cfg/construct.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl CFGBuilder {
9797
ast::PatEnum(_, None) |
9898
ast::PatLit(*) |
9999
ast::PatRange(*) |
100-
ast::PatWild => {
100+
ast::PatWild | ast::PatWildMulti => {
101101
self.add_node(pat.id, [pred])
102102
}
103103

src/librustc/middle/check_match.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ fn is_useful_specialized(cx: &MatchCheckCtxt,
333333
fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
334334
let pat = raw_pat(p);
335335
match pat.node {
336-
PatWild => { None }
336+
PatWild | PatWildMulti => { None }
337337
PatIdent(_, _, _) | PatEnum(_, _) => {
338338
match cx.tcx.def_map.find(&pat.id) {
339339
Some(&DefVariant(_, id, _)) => Some(variant(id)),
@@ -369,7 +369,7 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
369369
fn is_wild(cx: &MatchCheckCtxt, p: @Pat) -> bool {
370370
let pat = raw_pat(p);
371371
match pat.node {
372-
PatWild => { true }
372+
PatWild | PatWildMulti => { true }
373373
PatIdent(_, _, _) => {
374374
match cx.tcx.def_map.find(&pat.id) {
375375
Some(&DefVariant(_, _, _)) | Some(&DefStatic(*)) => { false }
@@ -532,6 +532,10 @@ fn wild() -> @Pat {
532532
@Pat {id: 0, node: PatWild, span: dummy_sp()}
533533
}
534534

535+
fn wild_multi() -> @Pat {
536+
@Pat {id: 0, node: PatWildMulti, span: dummy_sp()}
537+
}
538+
535539
fn specialize(cx: &MatchCheckCtxt,
536540
r: &[@Pat],
537541
ctor_id: &ctor,
@@ -546,6 +550,9 @@ fn specialize(cx: &MatchCheckCtxt,
546550
PatWild => {
547551
Some(vec::append(vec::from_elem(arity, wild()), r.tail()))
548552
}
553+
PatWildMulti => {
554+
Some(vec::append(vec::from_elem(arity, wild_multi()), r.tail()))
555+
}
549556
PatIdent(_, _, _) => {
550557
match cx.tcx.def_map.find(&pat_id) {
551558
Some(&DefVariant(_, id, _)) => {
@@ -849,7 +856,7 @@ fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat) -> bool {
849856
PatIdent(_, _, Some(sub)) => {
850857
is_refutable(cx, sub)
851858
}
852-
PatWild | PatIdent(_, _, None) => { false }
859+
PatWild | PatWildMulti | PatIdent(_, _, None) => { false }
853860
PatLit(@Expr {node: ExprLit(@Spanned { node: lit_nil, _}), _}) => {
854861
// "()"
855862
false

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ impl mem_categorization_ctxt {
876876
op(cmt, pat);
877877

878878
match pat.node {
879-
ast::PatWild => {
879+
ast::PatWild | ast::PatWildMulti => {
880880
// _
881881
}
882882

src/librustc/middle/pat_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn pat_is_binding(dm: resolve::DefMap, pat: @Pat) -> bool {
6565
pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @Pat) -> bool {
6666
match pat.node {
6767
PatIdent(*) => pat_is_binding(dm, pat),
68-
PatWild => true,
68+
PatWild | PatWildMulti => true,
6969
_ => false
7070
}
7171
}

src/librustc/middle/trans/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ fn enter_default<'r>(bcx: @mut Block,
545545
// Collect all of the matches that can match against anything.
546546
let matches = do enter_match(bcx, dm, m, col, val) |p| {
547547
match p.node {
548-
ast::PatWild | ast::PatTup(_) => Some(~[]),
548+
ast::PatWild | ast::PatWildMulti | ast::PatTup(_) => Some(~[]),
549549
ast::PatIdent(_, _, None) if pat_is_binding(dm, p) => Some(~[]),
550550
_ => None
551551
}
@@ -2234,7 +2234,7 @@ fn bind_irrefutable_pat(bcx: @mut Block,
22342234
pat.span,
22352235
format!("vector patterns are never irrefutable!"));
22362236
}
2237-
ast::PatWild | ast::PatLit(_) | ast::PatRange(_, _) => ()
2237+
ast::PatWild | ast::PatWildMulti | ast::PatLit(_) | ast::PatRange(_, _) => ()
22382238
}
22392239
return bcx;
22402240
}

src/librustc/middle/trans/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2429,7 +2429,7 @@ fn populate_scope_map(cx: &mut CrateContext,
24292429
}
24302430
}
24312431

2432-
ast::PatWild => {
2432+
ast::PatWild | ast::PatWildMulti => {
24332433
scope_map.insert(pat.id, scope_stack.last().scope_metadata);
24342434
}
24352435

src/librustc/middle/typeck/check/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::Pat, expected: ty::t) {
414414
let tcx = pcx.fcx.ccx.tcx;
415415

416416
match pat.node {
417-
ast::PatWild => {
417+
ast::PatWild | ast::PatWildMulti => {
418418
fcx.write_ty(pat.id, expected);
419419
}
420420
ast::PatLit(lt) => {

src/librustc/middle/typeck/check/regionck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ pub mod guarantor {
12191219
rcx.fcx.pat_to_str(pat), guarantor);
12201220

12211221
match pat.node {
1222-
ast::PatWild => {}
1222+
ast::PatWild | ast::PatWildMulti => {}
12231223
ast::PatIdent(ast::BindByRef(_), _, opt_p) => {
12241224
link(rcx, pat.span, pat.id, guarantor);
12251225

src/librustdoc/clean.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,7 @@ fn name_from_pat(p: &ast::Pat) -> ~str {
11371137
use syntax::ast::*;
11381138
match p.node {
11391139
PatWild => ~"_",
1140+
PatWildMulti => ~"..",
11401141
PatIdent(_, ref p, _) => path_to_str(p),
11411142
PatEnum(ref p, _) => path_to_str(p),
11421143
PatStruct(*) => fail!("tried to get argument name from pat_struct, \

src/libsyntax/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ pub enum BindingMode {
337337
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
338338
pub enum Pat_ {
339339
PatWild,
340+
PatWildMulti,
340341
// A pat_ident may either be a new bound variable,
341342
// or a nullary enum (in which case the second field
342343
// is None).

src/libsyntax/ast_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ pub fn walk_pat(pat: @Pat, it: &fn(@Pat) -> bool) -> bool {
657657
slice.iter().advance(|&p| walk_pat(p, |p| it(p))) &&
658658
after.iter().advance(|&p| walk_pat(p, |p| it(p)))
659659
}
660-
PatWild | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
660+
PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
661661
PatEnum(_, _) => {
662662
true
663663
}

src/libsyntax/fold.rs

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ pub trait ast_fold {
174174
fn fold_pat(&self, p: @Pat) -> @Pat {
175175
let node = match p.node {
176176
PatWild => PatWild,
177+
PatWildMulti => PatWildMulti,
177178
PatIdent(binding_mode, ref pth, ref sub) => {
178179
PatIdent(binding_mode,
179180
self.fold_path(pth),

src/libsyntax/parse/obsolete.rs

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ pub enum ObsoleteSyntax {
3939
ObsoleteConstPointer,
4040
ObsoleteEmptyImpl,
4141
ObsoleteLoopAsContinue,
42+
ObsoleteEnumWildcard,
43+
ObsoleteStructWildcard,
44+
ObsoleteVecDotDotWildcard
4245
}
4346

4447
impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -113,6 +116,18 @@ impl ParserObsoleteMethods for Parser {
113116
"`loop` is now only used for loops and `continue` is used for \
114117
skipping iterations"
115118
),
119+
ObsoleteEnumWildcard => (
120+
"enum wildcard",
121+
"use `..` instead of `*` for matching all enum fields"
122+
),
123+
ObsoleteStructWildcard => (
124+
"struct wildcard",
125+
"use `..` instead of `_` for matching trailing struct fields"
126+
),
127+
ObsoleteVecDotDotWildcard => (
128+
"vec slice wildcard",
129+
"use `..` instead of `.._` for matching slices"
130+
),
116131
};
117132

118133
self.report(sp, kind, kind_str, desc);

src/libsyntax/parse/parser.rs

+43-10
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use ast::{MutImmutable, MutMutable, mac_, mac_invoc_tt, matcher, match_nontermin
4343
use ast::{match_seq, match_tok, method, mt, BiMul, Mutability};
4444
use ast::{named_field, UnNeg, noreturn, UnNot, Pat, PatBox, PatEnum};
4545
use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
46-
use ast::{PatTup, PatUniq, PatWild, private};
46+
use ast::{PatTup, PatUniq, PatWild, PatWildMulti, private};
4747
use ast::{BiRem, required};
4848
use ast::{ret_style, return_val, BiShl, BiShr, Stmt, StmtDecl};
4949
use ast::{StmtExpr, StmtSemi, StmtMac, struct_def, struct_field};
@@ -2724,17 +2724,35 @@ impl Parser {
27242724
}
27252725
}
27262726

2727-
let subpat = self.parse_pat();
27282727
if is_slice {
2729-
match subpat {
2730-
@ast::Pat { node: PatWild, _ } => (),
2731-
@ast::Pat { node: PatIdent(_, _, _), _ } => (),
2732-
@ast::Pat { span, _ } => self.span_fatal(
2733-
span, "expected an identifier or `_`"
2734-
)
2728+
if *self.token == token::COMMA || *self.token == token::RBRACKET {
2729+
slice = Some(@ast::Pat {
2730+
id: ast::DUMMY_NODE_ID,
2731+
node: PatWildMulti,
2732+
span: *self.span,
2733+
})
2734+
} else {
2735+
let subpat = self.parse_pat();
2736+
match subpat {
2737+
@ast::Pat { id, node: PatWild, span } => {
2738+
// NOTE #5830 activate after snapshot
2739+
// self.obsolete(*self.span, ObsoleteVecDotDotWildcard);
2740+
slice = Some(@ast::Pat {
2741+
id: id,
2742+
node: PatWildMulti,
2743+
span: span
2744+
})
2745+
},
2746+
@ast::Pat { node: PatIdent(_, _, _), _ } => {
2747+
slice = Some(subpat);
2748+
}
2749+
@ast::Pat { span, _ } => self.span_fatal(
2750+
span, "expected an identifier or nothing"
2751+
)
2752+
}
27352753
}
2736-
slice = Some(subpat);
27372754
} else {
2755+
let subpat = self.parse_pat();
27382756
if before_slice {
27392757
before.push(subpat);
27402758
} else {
@@ -2755,7 +2773,12 @@ impl Parser {
27552773
if first { first = false; }
27562774
else { self.expect(&token::COMMA); }
27572775

2776+
etc = *self.token == token::UNDERSCORE || *self.token == token::DOTDOT;
27582777
if *self.token == token::UNDERSCORE {
2778+
// NOTE #5830 activate after snapshot
2779+
// self.obsolete(*self.span, ObsoleteStructWildcard);
2780+
}
2781+
if etc {
27592782
self.bump();
27602783
if *self.token != token::RBRACE {
27612784
self.fatal(
@@ -3016,9 +3039,19 @@ impl Parser {
30163039
_ => false,
30173040
}
30183041
};
3019-
if is_star {
3042+
let is_dotdot = do self.look_ahead(1) |t| {
3043+
match *t {
3044+
token::DOTDOT => true,
3045+
_ => false,
3046+
}
3047+
};
3048+
if is_star | is_dotdot {
30203049
// This is a "top constructor only" pat
30213050
self.bump();
3051+
if is_star {
3052+
// NOTE #5830 activate after snapshot
3053+
// self.obsolete(*self.span, ObsoleteEnumWildcard);
3054+
}
30223055
self.bump();
30233056
self.expect(&token::RPAREN);
30243057
pat = PatEnum(enum_path, None);

src/libsyntax/print/pprust.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,7 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
16131613
is that it doesn't matter */
16141614
match pat.node {
16151615
ast::PatWild => word(s.s, "_"),
1616+
ast::PatWildMulti => word(s.s, ".."),
16161617
ast::PatIdent(binding_mode, ref path, sub) => {
16171618
match binding_mode {
16181619
ast::BindByRef(mutbl) => {
@@ -1701,7 +1702,12 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
17011702
}
17021703
for &p in slice.iter() {
17031704
if !before.is_empty() { word_space(s, ","); }
1704-
word(s.s, "..");
1705+
match p {
1706+
@ast::Pat { node: ast::PatWildMulti, _ } => {
1707+
// this case is handled by print_pat
1708+
}
1709+
_ => word(s.s, ".."),
1710+
}
17051711
print_pat(s, p);
17061712
if !after.is_empty() { word_space(s, ","); }
17071713
}

src/libsyntax/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ pub fn walk_pat<E:Clone, V:Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E) {
375375
visitor.visit_expr(lower_bound, env.clone());
376376
visitor.visit_expr(upper_bound, env)
377377
}
378-
PatWild => (),
378+
PatWild | PatWildMulti => (),
379379
PatVec(ref prepattern, ref slice_pattern, ref postpatterns) => {
380380
for prepattern in prepattern.iter() {
381381
visitor.visit_pat(*prepattern, env.clone())
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo(int, int, int, int);
12+
struct Bar{a: int, b: int, c: int, d: int}
13+
14+
pub fn main() {
15+
let Foo(..) = Foo(5, 5, 5, 5);
16+
let Foo(*) = Foo(5, 5, 5, 5);
17+
let Bar{..} = Bar{a: 5, b: 5, c: 5, d: 5};
18+
let Bar{_} = Bar{a: 5, b: 5, c: 5, d: 5};
19+
//let (..) = (5, 5, 5, 5);
20+
//let Foo(a, b, ..) = Foo(5, 5, 5, 5);
21+
//let Foo(.., d) = Foo(5, 5, 5, 5);
22+
//let (a, b, ..) = (5, 5, 5, 5);
23+
//let (.., c, d) = (5, 5, 5, 5);
24+
let Bar{b: b, ..} = Bar{a: 5, b: 5, c: 5, d: 5};
25+
let Bar{b: b, _} = Bar{a: 5, b: 5, c: 5, d: 5};
26+
match [5, 5, 5, 5] {
27+
[..] => { }
28+
}
29+
match [5, 5, 5, 5] {
30+
[a, ..] => { }
31+
}
32+
match [5, 5, 5, 5] {
33+
[.., b] => { }
34+
}
35+
match [5, 5, 5, 5] {
36+
[a, .., b] => { }
37+
}
38+
match [5, 5, 5] {
39+
[.._] => { }
40+
}
41+
match [5, 5, 5] {
42+
[a, .._] => { }
43+
}
44+
match [5, 5, 5] {
45+
[.._, a] => { }
46+
}
47+
match [5, 5, 5] {
48+
[a, .._, b] => { }
49+
}
50+
}

0 commit comments

Comments
 (0)