Skip to content

Commit 9dd5527

Browse files
committed
Leverage mir-opt to encode tests for EndRegion.
The tests use `-Z identify_regions` so one can eyeball output for sanity. The tests with closures use `-Z span_free_formats` so that host-specific paths do not get embedded into the dumped MIR. The tests check against MIR dump output immediately prior to borrowck (determined by hand to be the dump from after the "qualify-consts" pass) since that is when `EndRegion` will be most relevant in the near term.
1 parent 0a5211e commit 9dd5527

File tree

10 files changed

+705
-1
lines changed

10 files changed

+705
-1
lines changed

src/test/mir-opt/README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,32 @@ All the test information is in comments so the test is runnable.
2222

2323
For each $file_name, compiletest expects [$expected_line_0, ...,
2424
$expected_line_N] to appear in the dumped MIR in order. Currently it allows
25-
other non-matched lines before, after and in-between.
25+
other non-matched lines before, after and in-between. Note that this includes
26+
lines that end basic blocks or begin new ones; it is good practice
27+
in your tests to include the terminator for each of your basic blocks as an
28+
internal sanity check guarding against a test like:
29+
30+
```
31+
bb0: {
32+
StorageLive(_1);
33+
_1 = const true;
34+
StorageDead(_1);
35+
}
36+
```
37+
38+
that will inadvertantly pattern-matching against:
39+
40+
```
41+
bb0: {
42+
StorageLive(_1);
43+
_1 = const true;
44+
goto -> bb1
45+
}
46+
bb1: {
47+
StorageDead(_1);
48+
return;
49+
}
50+
```
2651

2752
Lines match ignoring whitespace, and the prefix "//" is removed.
2853

src/test/mir-opt/end_region_1.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z identify_regions
12+
// ignore-tidy-linelength
13+
14+
// This is just about the simplest program that exhibits an EndRegion.
15+
16+
fn main() {
17+
let a = 3;
18+
let b = &a;
19+
}
20+
21+
// END RUST SOURCE
22+
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
23+
// let mut _0: ();
24+
// let _1: i32;
25+
// let _2: &'6_1rce i32;
26+
//
27+
// bb0: {
28+
// StorageLive(_1);
29+
// _1 = const 3i32;
30+
// StorageLive(_2);
31+
// _2 = &'6_1rce _1;
32+
// _0 = ();
33+
// StorageDead(_2);
34+
// EndRegion('6_1rce);
35+
// StorageDead(_1);
36+
// return;
37+
// }
38+
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_2.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z identify_regions
12+
// ignore-tidy-linelength
13+
14+
// We will EndRegion for borrows in a loop that occur before break but
15+
// not those after break.
16+
17+
fn main() {
18+
loop {
19+
let a = true;
20+
let b = &a;
21+
if a { break; }
22+
let c = &a;
23+
}
24+
}
25+
26+
// END RUST SOURCE
27+
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
28+
// let mut _0: ();
29+
// let _2: bool;
30+
// let _3: &'7_1rce bool;
31+
// let _7: &'7_3rce bool;
32+
// let mut _4: ();
33+
// let mut _5: bool;
34+
// bb0: {
35+
// goto -> bb1;
36+
// }
37+
// bb1: {
38+
// StorageLive(_2);
39+
// _2 = const true;
40+
// StorageLive(_3);
41+
// _3 = &'7_1rce _2;
42+
// StorageLive(_5);
43+
// _5 = _2;
44+
// switchInt(_5) -> [0u8: bb3, otherwise: bb2];
45+
// }
46+
// bb2: {
47+
// _0 = ();
48+
// StorageDead(_5);
49+
// StorageDead(_3);
50+
// EndRegion('7_1rce);
51+
// StorageDead(_2);
52+
// return;
53+
// }
54+
// bb3: {
55+
// StorageDead(_5);
56+
// StorageLive(_7);
57+
// _7 = &'7_3rce _2;
58+
// _1 = ();
59+
// StorageDead(_7);
60+
// EndRegion('7_3rce);
61+
// StorageDead(_3);
62+
// EndRegion('7_1rce);
63+
// StorageDead(_2);
64+
// goto -> bb1;
65+
// }
66+
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_3.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z identify_regions
12+
// ignore-tidy-linelength
13+
14+
// Binding the borrow's subject outside the loop does not increase the
15+
// scope of the borrow.
16+
17+
fn main() {
18+
let mut a;
19+
loop {
20+
a = true;
21+
let b = &a;
22+
if a { break; }
23+
let c = &a;
24+
}
25+
}
26+
27+
// END RUST SOURCE
28+
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
29+
// let mut _0: ();
30+
// let mut _1: bool;
31+
// let _3: &'9_1rce bool;
32+
// let _7: &'9_3rce bool;
33+
// let mut _2: ();
34+
// let mut _4: ();
35+
// let mut _5: bool;
36+
//
37+
// bb0: {
38+
// StorageLive(_1);
39+
// goto -> bb1;
40+
// }
41+
// bb1: {
42+
// _1 = const true;
43+
// StorageLive(_3);
44+
// _3 = &'9_1rce _1;
45+
// StorageLive(_5);
46+
// _5 = _1;
47+
// switchInt(_5) -> [0u8: bb3, otherwise: bb2];
48+
// }
49+
// bb2: {
50+
// _0 = ();
51+
// StorageDead(_5);
52+
// StorageDead(_3);
53+
// EndRegion('9_1rce);
54+
// StorageDead(_1);
55+
// return;
56+
// }
57+
// bb3: {
58+
// _4 = ();
59+
// StorageDead(_5);
60+
// StorageLive(_7);
61+
// _7 = &'9_3rce _1;
62+
// _2 = ();
63+
// StorageDead(_7);
64+
// EndRegion('9_3rce);
65+
// StorageDead(_3);
66+
// EndRegion('9_1rce);
67+
// goto -> bb1;
68+
// }
69+
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_4.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z identify_regions
12+
// ignore-tidy-linelength
13+
14+
// Unwinding should EndRegion for in-scope borrows: Direct borrows.
15+
16+
fn main() {
17+
let d = D(0);
18+
let a = 0;
19+
let b = &a;
20+
foo(*b);
21+
let c = &a;
22+
}
23+
24+
struct D(i32);
25+
impl Drop for D { fn drop(&mut self) { println!("dropping D({})", self.0); } }
26+
27+
fn foo(i: i32) {
28+
if i > 0 { panic!("im positive"); }
29+
}
30+
31+
// END RUST SOURCE
32+
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
33+
// let mut _0: ();
34+
// let _1: D;
35+
// let _3: i32;
36+
// let _4: &'6_2rce i32;
37+
// let _7: &'6_4rce i32;
38+
// let mut _5: ();
39+
// let mut _6: i32;
40+
//
41+
// bb0: {
42+
// StorageLive(_1);
43+
// _1 = D::{{constructor}}(const 0i32,);
44+
// StorageLive(_3);
45+
// _3 = const 0i32;
46+
// StorageLive(_4);
47+
// _4 = &'6_2rce _3;
48+
// StorageLive(_6);
49+
// _6 = (*_4);
50+
// _5 = const foo(_6) -> [return: bb2, unwind: bb3];
51+
// }
52+
// bb1: {
53+
// resume;
54+
// }
55+
// bb2: {
56+
// StorageDead(_6);
57+
// StorageLive(_7);
58+
// _7 = &'6_4rce _3;
59+
// _0 = ();
60+
// StorageDead(_7);
61+
// EndRegion('6_4rce);
62+
// StorageDead(_4);
63+
// EndRegion('6_2rce);
64+
// StorageDead(_3);
65+
// drop(_1) -> bb4;
66+
// }
67+
// bb3: {
68+
// EndRegion('6_2rce);
69+
// drop(_1) -> bb1;
70+
// }
71+
// bb4: {
72+
// StorageDead(_1);
73+
// return;
74+
// }
75+
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

src/test/mir-opt/end_region_5.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z identify_regions -Z span_free_formats
12+
// ignore-tidy-linelength
13+
14+
// Unwinding should EndRegion for in-scope borrows: Borrowing via by-ref closure.
15+
16+
fn main() {
17+
let d = D(0);
18+
foo(|| -> i32 { d.0 });
19+
}
20+
21+
struct D(i32);
22+
impl Drop for D { fn drop(&mut self) { println!("dropping D({})", self.0); } }
23+
24+
fn foo<F>(f: F) where F: FnOnce() -> i32 {
25+
if f() > 0 { panic!("im positive"); }
26+
}
27+
28+
// END RUST SOURCE
29+
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
30+
// fn main() -> () {
31+
// let mut _0: ();
32+
// let _1: D;
33+
// let mut _2: ();
34+
// let mut _3: ();
35+
// let mut _4: [closure@NodeId(18) d: &'19mce D];
36+
// let mut _5: &'19mce D;
37+
//
38+
// bb0: {
39+
// StorageLive(_1);
40+
// _1 = D::{{constructor}}(const 0i32,);
41+
// StorageLive(_4);
42+
// StorageLive(_5);
43+
// _5 = &'19mce _1;
44+
// _4 = [closure@NodeId(18)] { d: _5 };
45+
// StorageDead(_5);
46+
// _3 = const foo(_4) -> [return: bb2, unwind: bb3];
47+
// }
48+
// bb1: {
49+
// resume;
50+
// }
51+
// bb2: {
52+
// StorageDead(_4);
53+
// EndRegion('19mce);
54+
// _0 = ();
55+
// drop(_1) -> bb4;
56+
// }
57+
// bb3: {
58+
// EndRegion('19mce);
59+
// drop(_1) -> bb1;
60+
// }
61+
// bb4: {
62+
// StorageDead(_1);
63+
// return;
64+
// }
65+
// }
66+
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir
67+
68+
// START rustc.node18.SimplifyCfg-qualify-consts.after.mir
69+
// fn main::{{closure}}(_1: [closure@NodeId(18) d:&'19mce D]) -> i32 {
70+
// let mut _0: i32;
71+
// let mut _2: i32;
72+
//
73+
// bb0: {
74+
// StorageLive(_2);
75+
// _2 = ((*(_1.0: &'19mce D)).0: i32);
76+
// _0 = _2;
77+
// StorageDead(_2);
78+
// return;
79+
// }
80+
// END rustc.node18.SimplifyCfg-qualify-consts.after.mir

0 commit comments

Comments
 (0)