Skip to content

Commit fc8765d

Browse files
committed
Auto merge of #61708 - dlrobertson:or-patterns-0, r=centril
Initial implementation of or-patterns An incomplete implementation of or-patterns (e.g. `Some(0 | 1)` as a pattern). This patch set aims to implement initial parsing of `or-patterns`. Related to: #54883 CC @alexreg @varkor r? @Centril
2 parents bd1da18 + 1870537 commit fc8765d

File tree

30 files changed

+241
-51
lines changed

30 files changed

+241
-51
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# `or_patterns`
2+
3+
The tracking issue for this feature is: [#54883]
4+
5+
[#54883]: https://github.com/rust-lang/rust/issues/54883
6+
7+
------------------------
8+
9+
The `or_pattern` language feature allows `|` to be arbitrarily nested within
10+
a pattern, for example, `Some(A(0) | B(1 | 2))` becomes a valid pattern.
11+
12+
## Examples
13+
14+
```rust,ignore
15+
#![feature(or_patterns)]
16+
17+
pub enum Foo {
18+
Bar,
19+
Baz,
20+
Quux,
21+
}
22+
23+
pub fn example(maybe_foo: Option<Foo>) {
24+
match maybe_foo {
25+
Some(Foo::Bar | Foo::Baz) => {
26+
println!("The value contained `Bar` or `Baz`");
27+
}
28+
Some(_) => {
29+
println!("The value did not contain `Bar` or `Baz`");
30+
}
31+
None => {
32+
println!("The value was `None`");
33+
}
34+
}
35+
}
36+
```

src/librustc/cfg/construct.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
140140
self.add_ast_node(pat.hir_id.local_id, &[pats_exit])
141141
}
142142

143+
PatKind::Or(ref pats) => {
144+
let branches: Vec<_> = pats.iter().map(|p| self.pat(p, pred)).collect();
145+
self.add_ast_node(pat.hir_id.local_id, &branches)
146+
}
147+
143148
PatKind::Slice(ref pre, ref vec, ref post) => {
144149
let pre_exit = self.pats_all(pre.iter(), pred);
145150
let vec_exit = self.pats_all(vec.iter(), pre_exit);

src/librustc/hir/intravisit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
709709
visitor.visit_pat(&field.pat)
710710
}
711711
}
712+
PatKind::Or(ref pats) => walk_list!(visitor, visit_pat, pats),
712713
PatKind::Tuple(ref tuple_elements, _) => {
713714
walk_list!(visitor, visit_pat, tuple_elements);
714715
}

src/librustc/hir/lowering.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,6 +2669,9 @@ impl<'a> LoweringContext<'a> {
26692669
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
26702670
hir::PatKind::TupleStruct(qpath, pats, ddpos)
26712671
}
2672+
PatKind::Or(ref pats) => {
2673+
hir::PatKind::Or(pats.iter().map(|x| self.lower_pat(x)).collect())
2674+
}
26722675
PatKind::Path(ref qself, ref path) => {
26732676
let qpath = self.lower_qpath(
26742677
p.id,

src/librustc/hir/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ impl Pat {
881881
PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
882882
s.iter().all(|p| p.walk_(it))
883883
}
884+
PatKind::Or(ref pats) => pats.iter().all(|p| p.walk_(it)),
884885
PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
885886
s.walk_(it)
886887
}
@@ -975,6 +976,10 @@ pub enum PatKind {
975976
/// `0 <= position <= subpats.len()`
976977
TupleStruct(QPath, HirVec<P<Pat>>, Option<usize>),
977978

979+
/// An or-pattern `A | B | C`.
980+
/// Invariant: `pats.len() >= 2`.
981+
Or(HirVec<P<Pat>>),
982+
978983
/// A path pattern for an unit struct/variant or a (maybe-associated) constant.
979984
Path(QPath),
980985

src/librustc/hir/print.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,9 @@ impl<'a> State<'a> {
16871687
self.s.space();
16881688
self.s.word("}");
16891689
}
1690+
PatKind::Or(ref pats) => {
1691+
self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(&p));
1692+
}
16901693
PatKind::Tuple(ref elts, ddpos) => {
16911694
self.popen();
16921695
if let Some(ddpos) = ddpos {

src/librustc/middle/mem_categorization.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
12901290
}
12911291
}
12921292

1293+
PatKind::Or(ref pats) => {
1294+
for pat in pats {
1295+
self.cat_pattern_(cmt.clone(), &pat, op)?;
1296+
}
1297+
}
1298+
12931299
PatKind::Binding(.., Some(ref subpat)) => {
12941300
self.cat_pattern_(cmt, &subpat, op)?;
12951301
}

src/librustc_mir/build/matches/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
657657
self.visit_bindings(&subpattern.pattern, subpattern_user_ty, f);
658658
}
659659
}
660+
PatternKind::Or { ref pats } => {
661+
for pat in pats {
662+
self.visit_bindings(&pat, pattern_user_ty.clone(), f);
663+
}
664+
}
660665
}
661666
}
662667
}

src/librustc_mir/build/matches/simplify.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
195195
candidate.match_pairs.push(MatchPair::new(place, subpattern));
196196
Ok(())
197197
}
198+
199+
PatternKind::Or { .. } => {
200+
Err(match_pair)
201+
}
198202
}
199203
}
200204
}

src/librustc_mir/build/matches/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8787
PatternKind::AscribeUserType { .. } |
8888
PatternKind::Array { .. } |
8989
PatternKind::Wild |
90+
PatternKind::Or { .. } |
9091
PatternKind::Binding { .. } |
9192
PatternKind::Leaf { .. } |
9293
PatternKind::Deref { .. } => {
@@ -130,6 +131,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
130131
PatternKind::Slice { .. } |
131132
PatternKind::Array { .. } |
132133
PatternKind::Wild |
134+
PatternKind::Or { .. } |
133135
PatternKind::Binding { .. } |
134136
PatternKind::AscribeUserType { .. } |
135137
PatternKind::Leaf { .. } |

0 commit comments

Comments
 (0)