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:
parent
a992a11913
commit
0a42dfc2fa
92 changed files with 533 additions and 482 deletions
|
|
@ -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!()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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."),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 | |
|
||||
|
|
|
|||
|
|
@ -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 | |
|
||||
|
|
|
|||
|
|
@ -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!()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue