Skip to content

Commit a060ed2

Browse files
authored
Rollup merge of rust-lang#119622 - Nadrieril:never_patterns_macros, r=compiler-errors
never patterns: Document behavior of never patterns with macros-by-example `never_patterns` makes `!` parse as a pattern so I was worried about breaking macros-by-example matching. Turns out we're fine because the cases that now match `$p:pat` used to error in the past. The only tricky case is `!` by itself, which backwards-compatibly doesn't match `$p:pat`. I have no idea why tho, I didn't think of that when I was implementing parsing 😅. This adds tests so we don't regress the current behavior. r? `@compiler-errors`
2 parents 60a2b43 + 718a433 commit a060ed2

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// check-pass
2+
// revisions: e2018 e2021
3+
//[e2018] edition:2018
4+
//[e2021] edition:2021
5+
#![feature(never_patterns)]
6+
#![allow(incomplete_features)]
7+
8+
#[derive(Debug, PartialEq, Eq)]
9+
struct Pattern;
10+
#[derive(Debug, PartialEq, Eq)]
11+
struct Never;
12+
#[derive(Debug, PartialEq, Eq)]
13+
struct Other;
14+
15+
macro_rules! detect_pat {
16+
($p:pat) => {
17+
Pattern
18+
};
19+
(!) => {
20+
Never
21+
};
22+
($($x:tt)*) => {
23+
Other
24+
};
25+
}
26+
27+
// For backwards-compatibility, all the cases that parse as `Pattern` under the feature gate must
28+
// have been parse errors before.
29+
fn main() {
30+
// For backwards compatibility this does not match `$p:pat`.
31+
assert_eq!(detect_pat!(!), Never);
32+
33+
// Edition 2018 parses both of these cases as `Other`. Both editions have been parsing the
34+
// first case as `Other` before, so we mustn't change that.
35+
assert_eq!(detect_pat!(! | true), Other);
36+
#[cfg(e2018)]
37+
assert_eq!(detect_pat!(true | !), Other);
38+
#[cfg(e2021)]
39+
assert_eq!(detect_pat!(true | !), Pattern);
40+
41+
// These are never patterns; they take no body when they're in a match arm.
42+
assert_eq!(detect_pat!((!)), Pattern);
43+
assert_eq!(detect_pat!((true, !)), Pattern);
44+
assert_eq!(detect_pat!(Some(!)), Pattern);
45+
46+
// These count as normal patterns.
47+
assert_eq!(detect_pat!((! | true)), Pattern);
48+
assert_eq!(detect_pat!((Ok(x) | Err(&!))), Pattern);
49+
}

tests/ui/rfcs/rfc-0000-never_patterns/parse.rs

+5
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,9 @@ fn parse(x: Void) {
6868
//~^ ERROR top-level or-patterns are not allowed in `let` bindings
6969
let (Ok(_) | Err(!)) = &res;
7070
let (Ok(_) | Err(&!)) = res.as_ref();
71+
72+
let ! = x;
73+
let y @ ! = x;
7174
}
75+
76+
fn foo(!: Void) {}

0 commit comments

Comments
 (0)