tests encoding current behavior for various cases of "binding" to _.

The `_` binding form is special, in that it encodes a "no-op": nothing is
actually bound, and thus nothing is moved or borrowed in this scenario. Usually
we do the "right" thing in all such cases. The exceptions are explicitly pointed
out in this test case, so that we keep track of whether they are eventually
fixed.
This commit is contained in:
Felix S. Klock II 2020-02-28 22:56:37 -05:00 committed by Mazdak Farrokhzad
parent 167510f776
commit 6e70849304
4 changed files with 243 additions and 0 deletions

View File

@ -0,0 +1,58 @@
// Issue #53114: NLL's borrow check had some deviations from the old borrow
// checker, and both had some deviations from our ideal state. This test
// captures the behavior of how `_` bindings are handled wiith respect to how we
// flag expressions that are meant to request unsafe blocks.
struct M;
fn let_wild_gets_moved_expr() {
let m = M;
drop(m);
let _ = m; // accepted, and want it to continue to be
let mm = (M, M); // variation on above with `_` in substructure
let (_x, _) = mm;
let (_, _y) = mm;
let (_, _) = mm;
}
fn match_moved_expr_to_wild() {
let m = M;
drop(m);
match m { _ => { } } // #53114: should eventually be accepted too
//~^ ERROR [E0382]
let mm = (M, M); // variation on above with `_` in substructure
match mm { (_x, _) => { } }
match mm { (_, _y) => { } }
//~^ ERROR [E0382]
match mm { (_, _) => { } }
//~^ ERROR [E0382]
}
fn let_wild_gets_borrowed_expr() {
let mut m = M;
let r = &mut m;
let _ = m; // accepted, and want it to continue to be
// let _x = m; // (compare with this error.)
drop(r);
let mut mm = (M, M); // variation on above with `_` in substructure
let (r1, r2) = (&mut mm.0, &mut mm.1);
let (_, _) = mm;
drop((r1, r2));
}
fn match_borrowed_expr_to_wild() {
let mut m = M;
let r = &mut m;
match m { _ => {} } ; // accepted, and want it to continue to be
drop(r);
let mut mm = (M, M); // variation on above with `_` in substructure
let (r1, r2) = (&mut mm.0, &mut mm.1);
match mm { (_, _) => { } }
drop((r1, r2));
}
fn main() { }

View File

@ -0,0 +1,34 @@
error[E0382]: use of moved value: `m`
--> $DIR/issue-53114-borrow-checks.rs:22:11
|
LL | let m = M;
| - move occurs because `m` has type `M`, which does not implement the `Copy` trait
LL | drop(m);
| - value moved here
LL | match m { _ => { } } // #53114: should eventually be accepted too
| ^ value used here after move
error[E0382]: use of moved value: `mm`
--> $DIR/issue-53114-borrow-checks.rs:27:11
|
LL | match mm { (_x, _) => { } }
| -- value moved here
LL | match mm { (_, _y) => { } }
| ^^ value used here after partial move
|
= note: move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `mm`
--> $DIR/issue-53114-borrow-checks.rs:29:11
|
LL | match mm { (_, _y) => { } }
| -- value moved here
LL |
LL | match mm { (_, _) => { } }
| ^^ value used here after partial move
|
= note: move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0382`.

View File

@ -0,0 +1,51 @@
// Issue #53114: NLL's borrow check had some deviations from the old borrow
// checker, and both had some deviations from our ideal state. This test
// captures the behavior of how `_` bindings are handled wiith respect to how we
// flag expressions that are meant to request unsafe blocks.
#![feature(untagged_unions)]
struct I(i64);
struct F(f64);
union U { a: I, b: F }
#[repr(packed)]
struct P {
a: &'static i8,
b: &'static u32,
}
fn let_wild_gets_unsafe_field() {
let u1 = U { a: I(0) };
let u2 = U { a: I(1) };
let p = P { a: &2, b: &3 };
let _ = &p.b; //~ WARN E0133
//~^ WARN will become a hard error
let _ = u1.a; // #53114: should eventually signal error as well
let _ = &u2.a; //~ ERROR [E0133]
// variation on above with `_` in substructure
let (_,) = (&p.b,); //~ WARN E0133
//~^ WARN will become a hard error
let (_,) = (u1.a,); //~ ERROR [E0133]
let (_,) = (&u2.a,); //~ ERROR [E0133]
}
fn match_unsafe_field_to_wild() {
let u1 = U { a: I(0) };
let u2 = U { a: I(1) };
let p = P { a: &2, b: &3 };
match &p.b { _ => { } } //~ WARN E0133
//~^ WARN will become a hard error
match u1.a { _ => { } } //~ ERROR [E0133]
match &u2.a { _ => { } } //~ ERROR [E0133]
// variation on above with `_` in substructure
match (&p.b,) { (_,) => { } } //~ WARN E0133
//~^ WARN will become a hard error
match (u1.a,) { (_,) => { } } //~ ERROR [E0133]
match (&u2.a,) { (_,) => { } } //~ ERROR [E0133]
}
fn main() { }

View File

@ -0,0 +1,100 @@
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:23:13
|
LL | let _ = &p.b;
| ^^^^
|
= note: `#[warn(safe_packed_borrows)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:26:13
|
LL | let _ = &u2.a;
| ^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:29:17
|
LL | let (_,) = (&p.b,);
| ^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:31:17
|
LL | let (_,) = (u1.a,);
| ^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:32:17
|
LL | let (_,) = (&u2.a,);
| ^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:39:11
|
LL | match &p.b { _ => { } }
| ^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:41:11
|
LL | match u1.a { _ => { } }
| ^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:42:11
|
LL | match &u2.a { _ => { } }
| ^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:45:12
|
LL | match (&p.b,) { (_,) => { } }
| ^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:47:12
|
LL | match (u1.a,) { (_,) => { } }
| ^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:48:12
|
LL | match (&u2.a,) { (_,) => { } }
| ^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0133`.