Skip to content

Commit e76cb8c

Browse files
committed
Auto merge of #116810 - cjgillot:mir-opt-check, r=oli-obk
Add FileCheck annotations to mir-opt tests. This PR makes compiletest run LLVM `FileCheck` tool on mir-opt tests. The check is *run by default*, except if disabled using `// skip-filecheck` comment. This ensures that we do not have a silently broken test. For now, the check is only run on the output of `--emit=mir`, ie. on PreCodegen MIR. I give an example on `reference_prop.rs`. r? `@oli-obk` cc `@RalfJung` Fixes #85180
2 parents c104861 + 328192b commit e76cb8c

File tree

353 files changed

+1444
-589
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

353 files changed

+1444
-589
lines changed

src/tools/compiletest/src/runtest.rs

+26-39
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::json;
1515
use crate::read2::{read2_abbreviated, Truncated};
1616
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
1717
use crate::ColorConfig;
18+
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
1819
use regex::{Captures, Regex};
1920
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
2021

@@ -229,6 +230,7 @@ enum Emit {
229230
None,
230231
Metadata,
231232
LlvmIr,
233+
Mir,
232234
Asm,
233235
LinkArgsAsm,
234236
}
@@ -2506,6 +2508,9 @@ impl<'test> TestCx<'test> {
25062508
Emit::LlvmIr => {
25072509
rustc.args(&["--emit", "llvm-ir"]);
25082510
}
2511+
Emit::Mir => {
2512+
rustc.args(&["--emit", "mir"]);
2513+
}
25092514
Emit::Asm => {
25102515
rustc.args(&["--emit", "asm"]);
25112516
}
@@ -3984,11 +3989,17 @@ impl<'test> TestCx<'test> {
39843989
fn run_mir_opt_test(&self) {
39853990
let pm = self.pass_mode();
39863991
let should_run = self.should_run(pm);
3987-
let emit_metadata = self.should_emit_metadata(pm);
3988-
let passes = self.get_passes();
39893992

3990-
let proc_res = self.compile_test_with_passes(should_run, emit_metadata, passes);
3991-
self.check_mir_dump();
3993+
let mut test_info = files_for_miropt_test(
3994+
&self.testpaths.file,
3995+
self.config.get_pointer_width(),
3996+
self.config.target_cfg().panic.for_miropt_test_tools(),
3997+
);
3998+
3999+
let passes = std::mem::take(&mut test_info.passes);
4000+
4001+
let proc_res = self.compile_test_with_passes(should_run, Emit::Mir, passes);
4002+
self.check_mir_dump(test_info);
39924003
if !proc_res.status.success() {
39934004
self.fatal_proc_rec("compilation failed!", &proc_res);
39944005
}
@@ -4002,37 +4013,12 @@ impl<'test> TestCx<'test> {
40024013
}
40034014
}
40044015

4005-
fn get_passes(&self) -> Vec<String> {
4006-
let files = miropt_test_tools::files_for_miropt_test(
4007-
&self.testpaths.file,
4008-
self.config.get_pointer_width(),
4009-
self.config.target_cfg().panic.for_miropt_test_tools(),
4010-
);
4011-
4012-
let mut out = Vec::new();
4013-
4014-
for miropt_test_tools::MiroptTestFiles {
4015-
from_file: _,
4016-
to_file: _,
4017-
expected_file: _,
4018-
passes,
4019-
} in files
4020-
{
4021-
out.extend(passes);
4022-
}
4023-
out
4024-
}
4025-
4026-
fn check_mir_dump(&self) {
4016+
fn check_mir_dump(&self, test_info: MiroptTest) {
40274017
let test_dir = self.testpaths.file.parent().unwrap();
40284018
let test_crate =
40294019
self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace("-", "_");
40304020

4031-
let suffix = miropt_test_tools::output_file_suffix(
4032-
&self.testpaths.file,
4033-
self.config.get_pointer_width(),
4034-
self.config.target_cfg().panic.for_miropt_test_tools(),
4035-
);
4021+
let MiroptTest { run_filecheck, suffix, files, passes: _ } = test_info;
40364022

40374023
if self.config.bless {
40384024
for e in
@@ -4047,14 +4033,7 @@ impl<'test> TestCx<'test> {
40474033
}
40484034
}
40494035

4050-
let files = miropt_test_tools::files_for_miropt_test(
4051-
&self.testpaths.file,
4052-
self.config.get_pointer_width(),
4053-
self.config.target_cfg().panic.for_miropt_test_tools(),
4054-
);
4055-
for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file, passes: _ } in
4056-
files
4057-
{
4036+
for MiroptTestFile { from_file, to_file, expected_file } in files {
40584037
let dumped_string = if let Some(after) = to_file {
40594038
self.diff_mir_files(from_file.into(), after.into())
40604039
} else {
@@ -4095,6 +4074,14 @@ impl<'test> TestCx<'test> {
40954074
}
40964075
}
40974076
}
4077+
4078+
if run_filecheck {
4079+
let output_path = self.output_base_name().with_extension("mir");
4080+
let proc_res = self.verify_with_filecheck(&output_path);
4081+
if !proc_res.status.success() {
4082+
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
4083+
}
4084+
}
40984085
}
40994086

41004087
fn diff_mir_files(&self, before: PathBuf, after: PathBuf) -> String {

src/tools/miropt-test-tools/src/lib.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
use std::fs;
22
use std::path::Path;
33

4-
pub struct MiroptTestFiles {
4+
pub struct MiroptTestFile {
55
pub expected_file: std::path::PathBuf,
66
pub from_file: String,
77
pub to_file: Option<String>,
8+
}
9+
10+
pub struct MiroptTest {
11+
pub run_filecheck: bool,
12+
pub suffix: String,
13+
pub files: Vec<MiroptTestFile>,
814
/// Vec of passes under test to be dumped
915
pub passes: Vec<String>,
1016
}
@@ -14,11 +20,7 @@ pub enum PanicStrategy {
1420
Abort,
1521
}
1622

17-
pub fn output_file_suffix(
18-
testfile: &Path,
19-
bit_width: u32,
20-
panic_strategy: PanicStrategy,
21-
) -> String {
23+
fn output_file_suffix(testfile: &Path, bit_width: u32, panic_strategy: PanicStrategy) -> String {
2224
let mut each_bit_width = false;
2325
let mut each_panic_strategy = false;
2426
for line in fs::read_to_string(testfile).unwrap().lines() {
@@ -47,16 +49,22 @@ pub fn files_for_miropt_test(
4749
testfile: &std::path::Path,
4850
bit_width: u32,
4951
panic_strategy: PanicStrategy,
50-
) -> Vec<MiroptTestFiles> {
52+
) -> MiroptTest {
5153
let mut out = Vec::new();
5254
let test_file_contents = fs::read_to_string(&testfile).unwrap();
5355

5456
let test_dir = testfile.parent().unwrap();
5557
let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
5658

5759
let suffix = output_file_suffix(testfile, bit_width, panic_strategy);
60+
let mut run_filecheck = true;
61+
let mut passes = Vec::new();
5862

5963
for l in test_file_contents.lines() {
64+
if l.starts_with("// skip-filecheck") {
65+
run_filecheck = false;
66+
continue;
67+
}
6068
if l.starts_with("// EMIT_MIR ") {
6169
let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
6270
let mut test_names = test_name.split(' ');
@@ -65,7 +73,6 @@ pub fn files_for_miropt_test(
6573
let mut expected_file;
6674
let from_file;
6775
let to_file;
68-
let mut passes = Vec::new();
6976

7077
if test_name.ends_with(".diff") {
7178
let trimmed = test_name.trim_end_matches(".diff");
@@ -114,9 +121,9 @@ pub fn files_for_miropt_test(
114121
}
115122
let expected_file = test_dir.join(expected_file);
116123

117-
out.push(MiroptTestFiles { expected_file, from_file, to_file, passes });
124+
out.push(MiroptTestFile { expected_file, from_file, to_file });
118125
}
119126
}
120127

121-
out
128+
MiroptTest { run_filecheck, suffix, files: out, passes }
122129
}

src/tools/tidy/src/mir_opt_tests.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) {
2626
for file in rs_files {
2727
for bw in [32, 64] {
2828
for ps in [PanicStrategy::Unwind, PanicStrategy::Abort] {
29-
for output_file in miropt_test_tools::files_for_miropt_test(&file, bw, ps) {
29+
let mir_opt_test = miropt_test_tools::files_for_miropt_test(&file, bw, ps);
30+
for output_file in mir_opt_test.files {
3031
output_files.remove(&output_file.expected_file);
3132
}
3233
}

tests/mir-opt/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,21 @@ This exists mainly for completeness and is rarely useful.
4949
```
5050
// EMIT_MIR $file_name_of_some_mir_dump.before.mir
5151
```
52+
53+
# FileCheck directives
54+
55+
The LLVM FileCheck tool is used to verify the contents of output MIR against `CHECK` directives
56+
present in the test file. This works on the runtime MIR, generated by `--emit=mir`, and not
57+
on the output of a individual passes.
58+
59+
Use `// skip-filecheck` to prevent FileCheck from running.
60+
61+
To check MIR for function `foo`, start with a `// CHECK-LABEL fn foo(` directive.
62+
63+
`{{regex}}` syntax allows to match `regex`.
64+
65+
`[[name:regex]]` syntax allows to bind `name` to a string matching `regex`, and refer to it
66+
as `[[name]]` in later directives, `regex` should be written not to match a leading space.
67+
Use `[[my_local:_.*]]` to name a local, and `[[my_bb:bb.*]]` to name a block.
68+
69+
Documentation for FileCheck is available here: https://www.llvm.org/docs/CommandGuide/FileCheck.html

tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir

+30-30
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
// MIR for `address_of_reborrow` after SimplifyCfg-initial
22

33
| User Type Annotations
4-
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:7:5: 7:18, inferred_ty: *const [i32; 10]
5-
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send
6-
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
7-
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
8-
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
9-
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
10-
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
11-
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
12-
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32]
13-
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32]
14-
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:18:5: 18:18, inferred_ty: *const [i32; 10]
15-
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send
16-
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
17-
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
18-
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
19-
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
20-
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
21-
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
22-
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32]
23-
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32]
24-
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10]
25-
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send
26-
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
27-
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
28-
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
29-
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
30-
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
31-
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
32-
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32]
33-
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32]
4+
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:8:5: 8:18, inferred_ty: *const [i32; 10]
5+
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:10:5: 10:25, inferred_ty: *const dyn std::marker::Send
6+
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
7+
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
8+
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
9+
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
10+
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
11+
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
12+
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
13+
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
14+
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:19:5: 19:18, inferred_ty: *const [i32; 10]
15+
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:21:5: 21:25, inferred_ty: *const dyn std::marker::Send
16+
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
17+
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
18+
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
19+
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
20+
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
21+
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
22+
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
23+
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
24+
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:29:5: 29:16, inferred_ty: *mut [i32; 10]
25+
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:31:5: 31:23, inferred_ty: *mut dyn std::marker::Send
26+
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
27+
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
28+
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
29+
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
30+
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
31+
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
32+
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
33+
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
3434
|
3535
fn address_of_reborrow() -> () {
3636
let mut _0: ();

tests/mir-opt/address_of.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// skip-filecheck
12
// EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
23

34
fn address_of_reborrow() {

tests/mir-opt/array_index_is_temporary.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// unit-test: SimplifyCfg-elaborate-drops
12
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
23
// Retagging (from Stacked Borrows) relies on the array index being a fresh
34
// temporary, so that side-effects cannot change it.
@@ -11,6 +12,12 @@ unsafe fn foo(z: *mut usize) -> u32 {
1112

1213
// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
1314
fn main() {
15+
// CHECK-LABEL: fn main(
16+
// CHECK: debug x => [[x:_.*]];
17+
// CHECK: debug y => [[y:_.*]];
18+
// CHECK: [[y]] = const 1_usize;
19+
// CHECK: [[tmp:_.*]] = [[y]];
20+
// CHECK: [[x]][[[tmp]]] =
1421
let mut x = [42, 43, 44];
1522
let mut y = 1;
1623
let z: *mut usize = &mut y;

0 commit comments

Comments
 (0)