@@ -4,4 +4,84 @@ In Rust, pattern matching and bindings have a few very helpful properties. The
4
4
compiler will check that bindings are irrefutable when made and that match arms
5
5
are exhaustive.
6
6
7
- ** TODO** : write this chapter.
7
+ ## Pattern usefulness
8
+
9
+ The central question that usefulness checking answers is:
10
+ "in this match expression, is that branch reachable?".
11
+ More precisely, it boils down to computing whether,
12
+ given a list of patterns we have already seen,
13
+ a given new pattern might match any new value.
14
+
15
+ For example, in the following match expression,
16
+ we ask in turn whether each pattern might match something
17
+ that wasn't matched by the patterns above it.
18
+ Here we see the 4th pattern is redundant with the 1st;
19
+ that branch will get an "unreachable" warning.
20
+ The 3rd pattern may or may not be useful,
21
+ depending on whether ` Foo ` has other variants than ` Bar ` .
22
+ Finally, we can ask whether the whole match is exhaustive
23
+ by asking whether the wildcard pattern (` _ ` )
24
+ is useful relative to the list of all the patterns in that match.
25
+ Here we can see that ` _ ` is useful (it would catch ` (false, None) ` );
26
+ this expression would therefore get a "non-exhaustive match" error.
27
+
28
+ ``` rust
29
+ // x: (bool, Option<Foo>)
30
+ match x {
31
+ (true , _ ) => {} // 1
32
+ (false , Some (Foo :: Bar )) => {} // 2
33
+ (false , Some (_ )) => {} // 3
34
+ (true , None ) => {} // 4
35
+ }
36
+ ```
37
+
38
+ Thus usefulness is used for two purposes:
39
+ detecting unreachable code (which is useful to the user),
40
+ and ensuring that matches are exhaustive (which is important for soundness).
41
+
42
+ ## Where it happens
43
+
44
+ This check is done to any expression that desugars to a match expression in MIR.
45
+ That includes actual ` match ` expressions,
46
+ but also anything that looks like pattern matching,
47
+ including ` if let ` , destructuring ` let ` , and similar expressions.
48
+
49
+ ``` rust
50
+ // `match`
51
+ // Usefulness can detect unreachable branches and forbid non-exhaustive matches.
52
+ match foo () {
53
+ Ok (x ) => x ,
54
+ Err (_ ) => panic! (),
55
+ }
56
+
57
+ // `if let`
58
+ // Usefulness can detect unreachable branches.
59
+ if let Some (x ) = foo () {
60
+ // ...
61
+ }
62
+
63
+ // `while let`
64
+ // Usefulness can detect infinite loops and dead loops.
65
+ while let Some (x ) = it . next () {
66
+ // ...
67
+ }
68
+
69
+ // Destructuring `let`
70
+ // Usefulness can forbid non-exhaustive patterns.
71
+ let Foo :: Bar (x , y ) = foo ();
72
+
73
+ // Destructuring function arguments
74
+ // Usefulness can forbid non-exhaustive patterns.
75
+ fn foo (Foo { x , y }: Foo ) {
76
+ // ...
77
+ }
78
+ ```
79
+
80
+ ## The algorithm
81
+
82
+ Exhaustiveness checking is implemented in [ check_match] .
83
+ The core of the algorithm is in [ _ match] .
84
+ That file contains a detailed description of the algorithm.
85
+
86
+ [ check_match ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/pattern/check_match/index.html
87
+ [ _match ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_build/thir/pattern/_match/index.html
0 commit comments