Tests: No longer emitting 0008, E0301, E0302.
This commit is contained in:
parent
642993e6dc
commit
c6bfb1e9fd
5 changed files with 6 additions and 113 deletions
|
@ -157,81 +157,6 @@ match x {
|
|||
See also the error E0303.
|
||||
"##,
|
||||
|
||||
E0008: r##"
|
||||
Names bound in match arms retain their type in pattern guards. As such, if a
|
||||
name is bound by move in a pattern, it should also be moved to wherever it is
|
||||
referenced in the pattern guard code. Doing so however would prevent the name
|
||||
from being available in the body of the match arm. Consider the following:
|
||||
|
||||
```compile_fail,E0008
|
||||
match Some("hi".to_string()) {
|
||||
Some(s) if s.len() == 0 => {}, // use s.
|
||||
_ => {},
|
||||
}
|
||||
```
|
||||
|
||||
The variable `s` has type `String`, and its use in the guard is as a variable of
|
||||
type `String`. The guard code effectively executes in a separate scope to the
|
||||
body of the arm, so the value would be moved into this anonymous scope and
|
||||
therefore becomes unavailable in the body of the arm.
|
||||
|
||||
The problem above can be solved by using the `ref` keyword.
|
||||
|
||||
```
|
||||
match Some("hi".to_string()) {
|
||||
Some(ref s) if s.len() == 0 => {},
|
||||
_ => {},
|
||||
}
|
||||
```
|
||||
|
||||
Though this example seems innocuous and easy to solve, the problem becomes clear
|
||||
when it encounters functions which consume the value:
|
||||
|
||||
```compile_fail,E0008
|
||||
struct A{}
|
||||
|
||||
impl A {
|
||||
fn consume(self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Some(A{});
|
||||
match a {
|
||||
Some(y) if y.consume() > 0 => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this situation, even the `ref` keyword cannot solve it, since borrowed
|
||||
content cannot be moved. This problem cannot be solved generally. If the value
|
||||
can be cloned, here is a not-so-specific solution:
|
||||
|
||||
```
|
||||
#[derive(Clone)]
|
||||
struct A{}
|
||||
|
||||
impl A {
|
||||
fn consume(self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Some(A{});
|
||||
match a{
|
||||
Some(ref y) if y.clone().consume() > 0 => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the value will be consumed in the pattern guard, using its clone will not
|
||||
move its ownership, so the code works.
|
||||
"##,
|
||||
|
||||
E0009: r##"
|
||||
In a pattern, all values that don't implement the `Copy` trait have to be bound
|
||||
the same way. The goal here is to avoid binding simultaneously by-move and
|
||||
|
@ -475,13 +400,15 @@ for item in xs {
|
|||
"##,
|
||||
|
||||
E0301: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Mutable borrows are not allowed in pattern guards, because matching cannot have
|
||||
side effects. Side effects could alter the matched object or the environment
|
||||
on which the match depends in such a way, that the match would not be
|
||||
exhaustive. For instance, the following would not match any arm if mutable
|
||||
borrows were allowed:
|
||||
|
||||
```compile_fail,E0301
|
||||
```compile_fail,E0596
|
||||
match Some(()) {
|
||||
None => { },
|
||||
option if option.take().is_none() => {
|
||||
|
@ -493,13 +420,15 @@ match Some(()) {
|
|||
"##,
|
||||
|
||||
E0302: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Assignments are not allowed in pattern guards, because matching cannot have
|
||||
side effects. Side effects could alter the matched object or the environment
|
||||
on which the match depends in such a way, that the match would not be
|
||||
exhaustive. For instance, the following would not match any arm if assignments
|
||||
were allowed:
|
||||
|
||||
```compile_fail,E0302
|
||||
```compile_fail,E0594
|
||||
match Some(()) {
|
||||
None => { },
|
||||
option if { option = None; false } => { },
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
fn main() {
|
||||
match Some(()) {
|
||||
None => { },
|
||||
option if option.take().is_none() => {},
|
||||
Some(_) => { } //~^ ERROR E0596
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
error[E0596]: cannot borrow `option` as mutable, as it is immutable for the pattern guard
|
||||
--> $DIR/E0301.rs:4:19
|
||||
|
|
||||
LL | option if option.take().is_none() => {},
|
||||
| ^^^^^^ cannot borrow as mutable
|
||||
|
|
||||
= note: variables bound in patterns are immutable until the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
|
@ -1,8 +0,0 @@
|
|||
fn main() {
|
||||
match Some(()) {
|
||||
None => { },
|
||||
option if { option = None; false } => { },
|
||||
//~^ ERROR cannot assign to `option`, as it is immutable for the pattern guard
|
||||
Some(_) => { }
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
error[E0594]: cannot assign to `option`, as it is immutable for the pattern guard
|
||||
--> $DIR/E0302.rs:4:21
|
||||
|
|
||||
LL | option if { option = None; false } => { },
|
||||
| ^^^^^^^^^^^^^ cannot assign
|
||||
|
|
||||
= note: variables bound in patterns are immutable until the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue