Fix debugger stepping behavior around match expressions

Previously, we would set up the source lines for `match` expressions so
that the code generated to perform the test of the scrutinee was matched
to the line of the arm that required the test and then jump from the arm
block to the "next" block was matched to all of the lines in the `match`
expression.

While that makes sense, it has the side effect of causing strange
stepping behavior in debuggers.

I've changed the source information so that all of the generated tests
are sourced to `match {scrutinee}` and the jumps are sourced to the last
line of the block they are inside. This resolves the weird stepping
behavior in all debuggers and resolves some instances of "ambiguous
symbol" errors in WinDbg preventing the user from setting breakpoints at
`match` expressions.
This commit is contained in:
Wesley Wiser 2021-07-23 18:55:36 -04:00
parent a992a11913
commit 0a42dfc2fa
92 changed files with 533 additions and 482 deletions

View file

@ -14,8 +14,8 @@ fn distinct_variant() {
// also used for the discriminant of `Foo`, which it would be if `a` was a
// reference.
let b = match y {
Foo::Y(_, ref mut b) => b,
//~^ ERROR cannot use `y`
Foo::Y(_, ref mut b) => b,
Foo::X => panic!()
};
@ -32,8 +32,9 @@ fn same_variant() {
};
let b = match y {
Foo::Y(ref mut b, _) => b, //~ ERROR cannot use `y`
//~| ERROR cannot borrow `y.0` as mutable
//~^ ERROR cannot use `y`
Foo::Y(ref mut b, _) => b,
//~^ ERROR cannot borrow `y.0` as mutable
Foo::X => panic!()
};

View file

@ -1,29 +1,29 @@
error[E0503]: cannot use `y` because it was mutably borrowed
--> $DIR/borrowck-anon-fields-variant.rs:17:7
--> $DIR/borrowck-anon-fields-variant.rs:16:19
|
LL | Foo::Y(ref mut a, _) => a,
| --------- borrow of `y.0` occurs here
...
LL | Foo::Y(_, ref mut b) => b,
| ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
LL | let b = match y {
| ^ use of borrowed `y.0`
...
LL | *a += 1;
| ------- borrow later used here
error[E0503]: cannot use `y` because it was mutably borrowed
--> $DIR/borrowck-anon-fields-variant.rs:35:7
--> $DIR/borrowck-anon-fields-variant.rs:34:19
|
LL | Foo::Y(ref mut a, _) => a,
| --------- borrow of `y.0` occurs here
...
LL | Foo::Y(ref mut b, _) => b,
| ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
LL | let b = match y {
| ^ use of borrowed `y.0`
...
LL | *a += 1;
| ------- borrow later used here
error[E0499]: cannot borrow `y.0` as mutable more than once at a time
--> $DIR/borrowck-anon-fields-variant.rs:35:14
--> $DIR/borrowck-anon-fields-variant.rs:36:14
|
LL | Foo::Y(ref mut a, _) => a,
| --------- first mutable borrow occurs here

View file

@ -164,9 +164,9 @@ fn main() {
let mut e = E::A(3);
let x = &mut e;
match e {
//~^ ERROR cannot use `e` because it was mutably borrowed
E::A(ref ax) =>
//~^ ERROR cannot borrow `e.0` as immutable because it is also borrowed as mutable
//~| ERROR cannot use `e` because it was mutably borrowed
println!("e.ax: {:?}", ax),
E::B { x: ref bx } =>
//~^ ERROR cannot borrow `e.x` as immutable because it is also borrowed as mutable

View file

@ -238,23 +238,22 @@ LL | drop(x);
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowck-describe-lvalue.rs:167:13
--> $DIR/borrowck-describe-lvalue.rs:166:15
|
LL | let x = &mut e;
| ------ borrow of `e` occurs here
LL | match e {
LL | E::A(ref ax) =>
| ^^^^^^^^^^^^ use of borrowed `e`
| ^ use of borrowed `e`
...
LL | drop(x);
| - borrow later used here
error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-describe-lvalue.rs:167:18
--> $DIR/borrowck-describe-lvalue.rs:168:18
|
LL | let x = &mut e;
| ------ mutable borrow occurs here
LL | match e {
...
LL | E::A(ref ax) =>
| ^^^^^^ immutable borrow occurs here
...

View file

@ -6,8 +6,8 @@ enum Foo {
fn match_enum() {
let mut foo = Foo::B;
let p = &mut foo;
let _ = match foo {
Foo::B => 1, //~ ERROR [E0503]
let _ = match foo { //~ ERROR [E0503]
Foo::B => 1,
_ => 2,
Foo::A(x) => x //~ ERROR [E0503]
};

View file

@ -1,11 +1,10 @@
error[E0503]: cannot use `foo` because it was mutably borrowed
--> $DIR/borrowck-match-already-borrowed.rs:10:9
--> $DIR/borrowck-match-already-borrowed.rs:9:19
|
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo {
LL | Foo::B => 1,
| ^^^^^^ use of borrowed `foo`
| ^^^ use of borrowed `foo`
...
LL | drop(p);
| - borrow later used here

View file

@ -10,11 +10,11 @@
fn main() {
let b = &mut true;
match b {
//~^ ERROR use of moved value: `b` [E0382]
&mut false => {},
_ if { (|| { let bar = b; *bar = false; })();
false } => { },
&mut true => { println!("You might think we should get here"); },
//~^ ERROR use of moved value: `b` [E0382]
_ => panic!("surely we could never get here, since rustc warns it is unreachable."),
}
}

View file

@ -1,16 +1,15 @@
error[E0382]: use of moved value: `b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:16:14
--> $DIR/issue-27282-move-match-input-into-guard.rs:12:5
|
LL | let b = &mut true;
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
LL | match b {
| ^^^^^^^ value used here after move
...
LL | _ if { (|| { let bar = b; *bar = false; })();
| -- - variable moved due to use in closure
| |
| value moved into closure here
LL | false } => { },
LL | &mut true => { println!("You might think we should get here"); },
| ^^^^ value used here after move
error: aborting due to previous error

View file

@ -65,11 +65,11 @@ LL | U8_MUT2 => true,
| ^^^^^^^
warning: any use of this value will cause an error
--> $DIR/const_refers_to_static_cross_crate.rs:32:51
--> $DIR/const_refers_to_static_cross_crate.rs:32:20
|
LL | / const U8_MUT3: &u8 = {
LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| | ^^^^^^^^^^^ constant accesses static
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
LL | |
LL | |
LL | |

View file

@ -65,11 +65,11 @@ LL | U8_MUT2 => true,
| ^^^^^^^
warning: any use of this value will cause an error
--> $DIR/const_refers_to_static_cross_crate.rs:32:51
--> $DIR/const_refers_to_static_cross_crate.rs:32:20
|
LL | / const U8_MUT3: &u8 = {
LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| | ^^^^^^^^^^^ constant accesses static
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
LL | |
LL | |
LL | |

View file

@ -15,8 +15,8 @@ impl Drop for Enum {
fn main() {
let foo = X(1);
drop(foo);
match foo {
X(1) => (), //~ ERROR use of moved value
match foo { //~ ERROR use of moved value
X(1) => (),
_ => unreachable!()
}

View file

@ -1,13 +1,12 @@
error[E0382]: use of moved value: `foo`
--> $DIR/issue-17385.rs:19:11
--> $DIR/issue-17385.rs:18:5
|
LL | let foo = X(1);
| --- move occurs because `foo` has type `X`, which does not implement the `Copy` trait
LL | drop(foo);
| --- value moved here
LL | match foo {
LL | X(1) => (),
| ^ value used here after move
| ^^^^^^^^^ value used here after move
error[E0382]: use of moved value: `e`
--> $DIR/issue-17385.rs:25:11

View file

@ -10,8 +10,8 @@ fn main() {
let f = &mut e;
let g = f;
match e {
Xyz::A => println!("a"),
//~^ cannot use `e` because it was mutably borrowed [E0503]
Xyz::A => println!("a"),
Xyz::B => println!("b"),
};
*g = Xyz::B;

View file

@ -1,11 +1,11 @@
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/borrowed-match-issue-45045.rs:13:9
--> $DIR/borrowed-match-issue-45045.rs:12:11
|
LL | let f = &mut e;
| ------ borrow of `e` occurs here
...
LL | Xyz::A => println!("a"),
| ^^^^^^ use of borrowed `e`
LL | let g = f;
LL | match e {
| ^ use of borrowed `e`
...
LL | *g = Xyz::B;
| ----------- borrow later used here

View file

@ -7,8 +7,8 @@ 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 {
(false, true) => 1, //~ ERROR cannot use `y.1` because it was mutably borrowed
match y { //~ ERROR cannot use `y.1` because it was mutably borrowed
(false, true) => 1,
(true, _) => {
r;
2

View file

@ -1,12 +1,12 @@
error[E0503]: cannot use `y.1` because it was mutably borrowed
--> $DIR/match-cfg-fake-edges2.rs:11:17
--> $DIR/match-cfg-fake-edges2.rs:10:5
|
LL | let r = &mut y.1;
| -------- borrow of `y.1` occurs here
...
LL | (false, true) => 1,
| ^^^^ use of borrowed `y.1`
LL | (true, _) => {
LL | match y {
| ^^^^^^^ use of borrowed `y.1`
...
LL | r;
| - borrow later used here

View file

@ -45,8 +45,9 @@ fn enum_example(mut e: E) {
E::W => panic!(),
};
match e { // Don't know that E uses a tag for its discriminant
//~^ ERROR
_ if false => (),
E::V(_, r) => (), //~ ERROR
E::V(_, r) => (),
E::W => (),
}
x;
@ -58,8 +59,9 @@ fn indirect_enum_example(mut f: &mut E) {
E::W => panic!(),
};
match f { // Don't know that E uses a tag for its discriminant
//~^ ERROR
_ if false => (),
E::V(_, r) => (), //~ ERROR
E::V(_, r) => (),
E::W => (),
}
x;
@ -77,7 +79,8 @@ fn match_on_muatbly_borrowed_ref(mut p: &bool) {
fn match_on_borrowed(mut t: bool) {
let x = &mut t;
match t {
true => (), //~ ERROR
//~^ ERROR
true => (),
false => (),
}
x;

View file

@ -1,41 +1,40 @@
error[E0503]: cannot use `e` because it was mutably borrowed
--> $DIR/match-on-borrowed.rs:49:9
--> $DIR/match-on-borrowed.rs:47:11
|
LL | E::V(ref mut x, _) => x,
| --------- borrow of `e.0` occurs here
...
LL | E::V(_, r) => (),
| ^^^^^^^^^^ use of borrowed `e.0`
LL | match e { // Don't know that E uses a tag for its discriminant
| ^ use of borrowed `e.0`
...
LL | x;
| - borrow later used here
error[E0503]: cannot use `*f` because it was mutably borrowed
--> $DIR/match-on-borrowed.rs:62:9
--> $DIR/match-on-borrowed.rs:61:11
|
LL | E::V(ref mut x, _) => x,
| --------- borrow of `f.0` occurs here
...
LL | E::V(_, r) => (),
| ^^^^^^^^^^ use of borrowed `f.0`
LL | match f { // Don't know that E uses a tag for its discriminant
| ^ use of borrowed `f.0`
...
LL | x;
| - borrow later used here
error[E0503]: cannot use `t` because it was mutably borrowed
--> $DIR/match-on-borrowed.rs:80:9
--> $DIR/match-on-borrowed.rs:81:5
|
LL | let x = &mut t;
| ------ borrow of `t` occurs here
LL | match t {
LL | true => (),
| ^^^^ use of borrowed `t`
| ^^^^^^^ use of borrowed `t`
...
LL | x;
| - borrow later used here
error[E0381]: use of possibly-uninitialized variable: `n`
--> $DIR/match-on-borrowed.rs:90:11
--> $DIR/match-on-borrowed.rs:93:11
|
LL | match n {}
| ^ use of possibly-uninitialized `n`

View file

@ -10,8 +10,8 @@ fn main() {
let mut x = NonExhaustiveMonovariant::Variant(1);
let y = &mut x;
match x {
NonExhaustiveMonovariant::Variant(_) => {},
//~^ ERROR cannot use `x` because it was mutably borrowed
NonExhaustiveMonovariant::Variant(_) => {},
_ => {},
}
drop(y);

View file

@ -1,11 +1,10 @@
error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-non-exhaustive.rs:13:9
--> $DIR/borrowck-non-exhaustive.rs:12:11
|
LL | let y = &mut x;
| ------ borrow of `x` occurs here
LL | match x {
LL | NonExhaustiveMonovariant::Variant(_) => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of borrowed `x`
| ^ use of borrowed `x`
...
LL | drop(y);
| - borrow later used here

View file

@ -55,10 +55,10 @@ LL | let U1 { a } = u1;
= 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/union-unsafe.rs:65:20
--> $DIR/union-unsafe.rs:65:12
|
LL | if let U1 { a: 12 } = u1 {}
| ^^ access to union field
| ^^^^^^^^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior