@@ -24,6 +24,16 @@ This means that perhaps some of the preceding patterns are too general, this one
2424is too specific or the ordering is incorrect.
2525"## ,
2626
27+ E0002 : r##"
28+ This error indicates that an empty match expression is illegal because the type
29+ it is matching on is non-empty (there exist values of this type). In safe code
30+ it is impossible to create an instance of an empty type, so empty match
31+ expressions are almost never desired. This error is typically fixed by adding
32+ one or more cases to the match expression.
33+
34+ An example of an empty type is `enum Empty { }`.
35+ "## ,
36+
2737E0003 : r##"
2838Not-a-Number (NaN) values can not be compared for equality and hence can never
2939match the input to a match expression. To match against NaN values, you should
@@ -54,14 +64,80 @@ E0006: r##"
5464Patterns used to bind names must be irrefutable, that is, they must guarantee that a
5565name will be extracted in all cases. If you encounter this error you probably need
5666to use a `match` or `if let` to deal with the possibility of failure.
67+ "## ,
68+
69+ E0007 : r##"
70+ This error indicates that the bindings in a match arm would require a value to
71+ be moved into more than one location, thus violating unique ownership. Code like
72+ the following is invalid as it requires the entire Option<String> to be moved
73+ into a variable called `op_string` while simultaneously requiring the inner
74+ String to be moved into a variable called `s`.
75+
76+ let x = Some("s".to_string());
77+ match x {
78+ op_string @ Some(s) => ...
79+ None => ...
80+ }
81+
82+ See also Error 303.
83+ "## ,
84+
85+ E0008 : r##"
86+ Names bound in match arms retain their type in pattern guards. As such, if a
87+ name is bound by move in a pattern, it should also be moved to wherever it is
88+ referenced in the pattern guard code. Doing so however would prevent the name
89+ from being available in the body of the match arm. Consider the following:
90+
91+ match Some("hi".to_string()) {
92+ Some(s) if s.len() == 0 => // use s.
93+ ...
94+ }
95+
96+ The variable `s` has type String, and its use in the guard is as a variable of
97+ type String. The guard code effectively executes in a separate scope to the body
98+ of the arm, so the value would be moved into this anonymous scope and therefore
99+ become unavailable in the body of the arm. Although this example seems
100+ innocuous, the problem is most clear when considering functions that take their
101+ argument by value.
102+
103+ match Some("hi".to_string()) {
104+ Some(s) if { drop(s); false } => (),
105+ Some(s) => // use s.
106+ ...
107+ }
108+
109+ The value would be dropped in the guard then become unavailable not only in the
110+ body of that arm but also in all subsequent arms! The solution is to bind by
111+ reference when using guards or refactor the entire expression, perhaps by
112+ putting the condition inside the body of the arm.
113+ "## ,
114+
115+ E0303 : r##"
116+ In certain cases it is possible for sub-bindings to violate memory safety.
117+ Updates to the borrow checker in a future version of Rust may remove this
118+ restriction, but for now patterns must be rewritten without sub-bindings.
119+
120+ // Code like this...
121+ match Some(5) {
122+ ref op_num @ Some(num) => ...
123+ None => ...
124+ }
125+
126+ // ... should be updated to code like this.
127+ match Some(5) {
128+ Some(num) => {
129+ let op_num = Some(num);
130+ ...
131+ }
132+ None => ...
133+ }
134+
135+ See also https://github.com/rust-lang/rust/issues/14587
57136"##
58137
59138}
60139
61140register_diagnostics ! {
62- E0002 ,
63- E0007 ,
64- E0008 ,
65141 E0009 ,
66142 E0010 ,
67143 E0011 ,
@@ -124,7 +200,6 @@ register_diagnostics! {
124200 E0300 , // unexpanded macro
125201 E0301 , // cannot mutable borrow in a pattern guard
126202 E0302 , // cannot assign in a pattern guard
127- E0303 , // pattern bindings are not allowed after an `@`
128203 E0304 , // expected signed integer constant
129204 E0305 , // expected constant
130205 E0306 , // expected positive integer for repeat count
0 commit comments