summaryrefslogtreecommitdiffstats
path: root/tests/ui/pattern/never_patterns.rs
blob: 915f3e75e7bf3ae9db6b2563b7558d8bfee39d35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#![feature(never_patterns)]
#![allow(incomplete_features)]

enum Void {}

fn main() {}

// The classic use for empty types.
fn safe_unwrap_result<T>(res: Result<T, Void>) {
    let Ok(_x) = res;
    // FIXME(never_patterns): These should be allowed
    let (Ok(_x) | Err(!)) = &res;
    //~^ ERROR: is not bound in all patterns
    let (Ok(_x) | Err(&!)) = res.as_ref();
    //~^ ERROR: is not bound in all patterns
}

// Check we only accept `!` where we want to.
fn never_pattern_location(void: Void) {
    // FIXME(never_patterns): Don't accept on a non-empty type.
    match Some(0) {
        None => {}
        Some(!),
    }
    // FIXME(never_patterns): Don't accept on an arbitrary type, even if there are no more branches.
    match () {
        () => {}
        !,
    }
    // FIXME(never_patterns): Don't accept even on an empty branch.
    match None::<Void> {
        None => {}
        !,
    }
    // FIXME(never_patterns): Let alone if the emptiness is behind a reference.
    match None::<&Void> {
        None => {}
        !,
    }
    // Participate in match ergonomics.
    match &void {
        !
    }
    match &&void {
        !
    }
    match &&void {
        &!
    }
    match &None::<Void> {
        None => {}
        Some(!)
    }
    match None::<&Void> {
        None => {}
        Some(!),
    }
    // Accept on a composite empty type.
    match None::<&(u32, Void)> {
        None => {}
        Some(&!),
    }
    // Accept on an simple empty type.
    match None::<Void> {
        None => {}
        Some(!),
    }
    match None::<&Void> {
        None => {}
        Some(&!),
    }
    match None::<&(u32, Void)> {
        None => {}
        Some(&(_, !)),
    }
}

fn never_and_bindings() {
    let x: Result<bool, &(u32, Void)> = Ok(false);

    // FIXME(never_patterns): Never patterns in or-patterns don't need to share the same bindings.
    match x {
        Ok(_x) | Err(&!) => {}
        //~^ ERROR: is not bound in all patterns
    }
    let (Ok(_x) | Err(&!)) = x;
    //~^ ERROR: is not bound in all patterns

    // FIXME(never_patterns): A never pattern mustn't have bindings.
    match x {
        Ok(_) => {}
        Err(&(_b, !)),
    }
    match x {
        Ok(_a) | Err(&(_b, !)) => {}
        //~^ ERROR: is not bound in all patterns
        //~| ERROR: is not bound in all patterns
    }
}