forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#69573 - pnkfelix:issue-53114-add-tests, r=Cen…
…tril 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. Cc rust-lang#53114. (This does not close the aforementioned issue; it just adds the tests encoding the current behavior, which we hope to eventually fix.)
- Loading branch information
Showing
4 changed files
with
300 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// 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 with respect to how we | ||
// flag expressions that are meant to request unsafe blocks. | ||
#![allow(irrefutable_let_patterns)] | ||
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 if_let_moved_expr_to_wild() { | ||
let m = M; | ||
drop(m); | ||
if let _ = m { } // #53114: should eventually be accepted too | ||
//~^ ERROR [E0382] | ||
|
||
let mm = (M, M); // variation on above with `_` in substructure | ||
if let (_x, _) = mm { } | ||
if let (_, _y) = mm { } | ||
//~^ ERROR [E0382] | ||
if let (_, _) = 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 if_let_borrowed_expr_to_wild() { | ||
let mut m = M; | ||
let r = &mut m; | ||
if let _ = 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); | ||
if let (_, _) = mm { } | ||
drop((r1, r2)); | ||
} | ||
|
||
fn main() { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
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[E0382]: use of moved value: `m` | ||
--> $DIR/issue-53114-borrow-checks.rs:36:16 | ||
| | ||
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 | if let _ = 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:41:22 | ||
| | ||
LL | if let (_x, _) = mm { } | ||
| -- value moved here | ||
LL | if let (_, _y) = mm { } | ||
| ^^ 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:43:21 | ||
| | ||
LL | if let (_, _y) = mm { } | ||
| -- value moved here | ||
LL | | ||
LL | if let (_, _) = 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 6 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0382`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 with 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() { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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`. |