Add tests
This commit is contained in:
parent
ceab6128fa
commit
50103ab14d
@ -3,15 +3,43 @@
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn all_patterns_are_tested() {
|
||||
// Even though `x` is never actually moved out of, we don't want borrowck results to be based on
|
||||
// whether MIR lowering reveals which patterns are unreachable.
|
||||
let x = String::new();
|
||||
let _ = match true {
|
||||
_ => {},
|
||||
_ => drop(x),
|
||||
};
|
||||
// Borrowck must not know the second arm is never run.
|
||||
drop(x); //~ ERROR use of moved value
|
||||
|
||||
let x = (String::new(), String::new());
|
||||
match x {
|
||||
(y, _) | (_, y) => (),
|
||||
}
|
||||
&x.0; //~ ERROR borrow of moved value
|
||||
// Borrowck must not know the second pattern never matches.
|
||||
&x.1; //~ ERROR borrow of moved value
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn guard_always_precedes_arm(y: i32) {
|
||||
let mut x;
|
||||
// x should always be initialized, as the only way to reach the arm is
|
||||
// through the guard.
|
||||
let mut x;
|
||||
match y {
|
||||
0 | 2 if { x = 2; true } => x,
|
||||
_ => 2,
|
||||
};
|
||||
|
||||
let mut x;
|
||||
match y {
|
||||
_ => 2,
|
||||
0 | 2 if { x = 2; true } => x,
|
||||
};
|
||||
|
||||
let mut x;
|
||||
match y {
|
||||
0 | 2 if let Some(()) = { x = 2; Some(()) } => x,
|
||||
@ -19,51 +47,58 @@ fn guard_always_precedes_arm(y: i32) {
|
||||
};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn guard_may_be_skipped(y: i32) {
|
||||
// Even though x *is* always initialized, we don't want to have borrowck results be based on
|
||||
// whether MIR lowering reveals which patterns are exhaustive.
|
||||
let x;
|
||||
match y {
|
||||
_ if { x = 2; true } => {},
|
||||
// Borrowck must not know the guard is always run.
|
||||
_ => drop(x), //~ ERROR used binding `x` is possibly-uninitialized
|
||||
};
|
||||
|
||||
let x;
|
||||
// Even though x *is* always initialized, we don't want to have borrowck
|
||||
// results be based on whether patterns are exhaustive.
|
||||
match y {
|
||||
_ if { x = 2; true } => 1,
|
||||
_ if {
|
||||
x; //~ ERROR E0381
|
||||
false
|
||||
} => 2,
|
||||
// Borrowck must not know the guard is always run.
|
||||
_ if { x; false } => 2, //~ ERROR used binding `x` isn't initialized
|
||||
_ => 3,
|
||||
};
|
||||
|
||||
let x;
|
||||
match y {
|
||||
_ if let Some(()) = { x = 2; Some(()) } => 1,
|
||||
_ if let Some(()) = {
|
||||
x; //~ ERROR E0381
|
||||
None
|
||||
} => 2,
|
||||
_ if let Some(()) = { x; None } => 2, //~ ERROR used binding `x` isn't initialized
|
||||
_ => 3,
|
||||
};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn guard_may_be_taken(y: bool) {
|
||||
let x = String::new();
|
||||
// Even though x *is* never moved before the use, we don't want to have
|
||||
// borrowck results be based on whether patterns are disjoint.
|
||||
let x = String::new();
|
||||
match y {
|
||||
false if { drop(x); true } => 1,
|
||||
true => {
|
||||
x; //~ ERROR use of moved value: `x`
|
||||
2
|
||||
}
|
||||
false => 3,
|
||||
false if { drop(x); true } => {},
|
||||
// Borrowck must not know the guard is not run in the `true` case.
|
||||
true => drop(x), //~ ERROR use of moved value: `x`
|
||||
false => {},
|
||||
};
|
||||
|
||||
// Fine in the other order.
|
||||
let x = String::new();
|
||||
match y {
|
||||
true => drop(x),
|
||||
false if { drop(x); true } => {},
|
||||
false => {},
|
||||
};
|
||||
|
||||
let x = String::new();
|
||||
match y {
|
||||
false if let Some(()) = { drop(x); Some(()) } => 1,
|
||||
true => {
|
||||
x; //~ ERROR use of moved value: `x`
|
||||
2
|
||||
}
|
||||
false => 3,
|
||||
false if let Some(()) = { drop(x); Some(()) } => {},
|
||||
true => drop(x), //~ ERROR use of moved value: `x`
|
||||
false => {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,72 @@
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:29:13
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:16:10
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
...
|
||||
LL | _ => drop(x),
|
||||
| - value moved here
|
||||
...
|
||||
LL | drop(x);
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | _ => drop(x.clone()),
|
||||
| ++++++++
|
||||
|
||||
error[E0382]: borrow of moved value: `x.0`
|
||||
--> $DIR/match-cfg-fake-edges.rs:22:5
|
||||
|
|
||||
LL | (y, _) | (_, y) => (),
|
||||
| - value moved here
|
||||
LL | }
|
||||
LL | &x.0;
|
||||
| ^^^^ value borrowed here after move
|
||||
|
|
||||
= note: move occurs because `x.0` has type `String`, which does not implement the `Copy` trait
|
||||
help: borrow this binding in the pattern to avoid moving the value
|
||||
|
|
||||
LL | (ref y, _) | (_, y) => (),
|
||||
| +++
|
||||
|
||||
error[E0382]: borrow of moved value: `x.1`
|
||||
--> $DIR/match-cfg-fake-edges.rs:24:5
|
||||
|
|
||||
LL | (y, _) | (_, y) => (),
|
||||
| - value moved here
|
||||
...
|
||||
LL | &x.1;
|
||||
| ^^^^ value borrowed here after move
|
||||
|
|
||||
= note: move occurs because `x.1` has type `String`, which does not implement the `Copy` trait
|
||||
help: borrow this binding in the pattern to avoid moving the value
|
||||
|
|
||||
LL | (y, _) | (_, ref y) => (),
|
||||
| +++
|
||||
|
||||
error[E0381]: used binding `x` is possibly-uninitialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:58:19
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
...
|
||||
LL | _ => drop(x),
|
||||
| - ^ `x` used here but it is possibly-uninitialized
|
||||
| |
|
||||
| if this pattern is matched, `x` is not initialized
|
||||
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:65:16
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
LL | match y {
|
||||
LL | _ if { x = 2; true } => 1,
|
||||
| ----- binding initialized here in some conditions
|
||||
LL | _ if {
|
||||
LL | x;
|
||||
| ^ `x` used here but it isn't initialized
|
||||
LL | // Borrowck must not know the guard is always run.
|
||||
LL | _ if { x; false } => 2,
|
||||
| ^ `x` used here but it isn't initialized
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
@ -16,16 +74,15 @@ LL | let x = 0;
|
||||
| +++
|
||||
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:39:13
|
||||
--> $DIR/match-cfg-fake-edges.rs:72:31
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
LL | match y {
|
||||
LL | _ if let Some(()) = { x = 2; Some(()) } => 1,
|
||||
| ----- binding initialized here in some conditions
|
||||
LL | _ if let Some(()) = {
|
||||
LL | x;
|
||||
| ^ `x` used here but it isn't initialized
|
||||
LL | _ if let Some(()) = { x; None } => 2,
|
||||
| ^ `x` used here but it isn't initialized
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
@ -33,40 +90,39 @@ LL | let x = 0;
|
||||
| +++
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:53:13
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
...
|
||||
LL | false if { drop(x); true } => 1,
|
||||
| - value moved here
|
||||
LL | true => {
|
||||
LL | x;
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | false if { drop(x.clone()); true } => 1,
|
||||
| ++++++++
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:63:13
|
||||
--> $DIR/match-cfg-fake-edges.rs:85:22
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
LL | match y {
|
||||
LL | false if let Some(()) = { drop(x); Some(()) } => 1,
|
||||
| - value moved here
|
||||
LL | true => {
|
||||
LL | x;
|
||||
| ^ value used here after move
|
||||
LL | false if { drop(x); true } => {},
|
||||
| - value moved here
|
||||
LL | // Borrowck must not know the guard is not run in the `true` case.
|
||||
LL | true => drop(x),
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | false if let Some(()) = { drop(x.clone()); Some(()) } => 1,
|
||||
LL | false if { drop(x.clone()); true } => {},
|
||||
| ++++++++
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:100:22
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
LL | match y {
|
||||
LL | false if let Some(()) = { drop(x); Some(()) } => {},
|
||||
| - value moved here
|
||||
LL | true => drop(x),
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | false if let Some(()) = { drop(x.clone()); Some(()) } => {},
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0381, E0382.
|
||||
For more information about an error, try `rustc --explain E0381`.
|
||||
|
@ -5,13 +5,20 @@ fn all_previous_tests_may_be_done(y: &mut (bool, bool)) {
|
||||
let r = &mut y.1;
|
||||
// We don't actually test y.1 to select the second arm, but we don't want
|
||||
// borrowck results to be based on the order we match patterns.
|
||||
match y { //~ ERROR cannot use `y.1` because it was mutably borrowed
|
||||
(false, true) => 1,
|
||||
(true, _) => {
|
||||
r;
|
||||
2
|
||||
}
|
||||
(false, _) => 3,
|
||||
match y {
|
||||
//~^ ERROR cannot use `y.1` because it was mutably borrowed
|
||||
(false, true) => {}
|
||||
// Borrowck must not know we don't test `y.1` when `y.0` is `true`.
|
||||
(true, _) => drop(r),
|
||||
(false, _) => {}
|
||||
};
|
||||
|
||||
// Fine in the other order.
|
||||
let r = &mut y.1;
|
||||
match y {
|
||||
(true, _) => drop(r),
|
||||
(false, true) => {}
|
||||
(false, _) => {}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@ LL | let r = &mut y.1;
|
||||
LL | match y {
|
||||
| ^^^^^^^ use of borrowed `y.1`
|
||||
...
|
||||
LL | r;
|
||||
| - borrow later used here
|
||||
LL | (true, _) => drop(r),
|
||||
| - borrow later used here
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user