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 https://github.com/rust-lang/rust/issues/85180
This commit is contained in:
bors 2023-10-19 16:53:52 +00:00
commit e76cb8c498
353 changed files with 1444 additions and 589 deletions

View File

@ -15,6 +15,7 @@ use crate::json;
use crate::read2::{read2_abbreviated, Truncated};
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
use crate::ColorConfig;
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
use regex::{Captures, Regex};
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@ -229,6 +230,7 @@ enum Emit {
None,
Metadata,
LlvmIr,
Mir,
Asm,
LinkArgsAsm,
}
@ -2506,6 +2508,9 @@ impl<'test> TestCx<'test> {
Emit::LlvmIr => {
rustc.args(&["--emit", "llvm-ir"]);
}
Emit::Mir => {
rustc.args(&["--emit", "mir"]);
}
Emit::Asm => {
rustc.args(&["--emit", "asm"]);
}
@ -3984,11 +3989,17 @@ impl<'test> TestCx<'test> {
fn run_mir_opt_test(&self) {
let pm = self.pass_mode();
let should_run = self.should_run(pm);
let emit_metadata = self.should_emit_metadata(pm);
let passes = self.get_passes();
let proc_res = self.compile_test_with_passes(should_run, emit_metadata, passes);
self.check_mir_dump();
let mut test_info = files_for_miropt_test(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
let passes = std::mem::take(&mut test_info.passes);
let proc_res = self.compile_test_with_passes(should_run, Emit::Mir, passes);
self.check_mir_dump(test_info);
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}
@ -4002,37 +4013,12 @@ impl<'test> TestCx<'test> {
}
}
fn get_passes(&self) -> Vec<String> {
let files = miropt_test_tools::files_for_miropt_test(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
let mut out = Vec::new();
for miropt_test_tools::MiroptTestFiles {
from_file: _,
to_file: _,
expected_file: _,
passes,
} in files
{
out.extend(passes);
}
out
}
fn check_mir_dump(&self) {
fn check_mir_dump(&self, test_info: MiroptTest) {
let test_dir = self.testpaths.file.parent().unwrap();
let test_crate =
self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace("-", "_");
let suffix = miropt_test_tools::output_file_suffix(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
let MiroptTest { run_filecheck, suffix, files, passes: _ } = test_info;
if self.config.bless {
for e in
@ -4047,14 +4033,7 @@ impl<'test> TestCx<'test> {
}
}
let files = miropt_test_tools::files_for_miropt_test(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file, passes: _ } in
files
{
for MiroptTestFile { from_file, to_file, expected_file } in files {
let dumped_string = if let Some(after) = to_file {
self.diff_mir_files(from_file.into(), after.into())
} else {
@ -4095,6 +4074,14 @@ impl<'test> TestCx<'test> {
}
}
}
if run_filecheck {
let output_path = self.output_base_name().with_extension("mir");
let proc_res = self.verify_with_filecheck(&output_path);
if !proc_res.status.success() {
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
}
}
}
fn diff_mir_files(&self, before: PathBuf, after: PathBuf) -> String {

View File

@ -1,10 +1,16 @@
use std::fs;
use std::path::Path;
pub struct MiroptTestFiles {
pub struct MiroptTestFile {
pub expected_file: std::path::PathBuf,
pub from_file: String,
pub to_file: Option<String>,
}
pub struct MiroptTest {
pub run_filecheck: bool,
pub suffix: String,
pub files: Vec<MiroptTestFile>,
/// Vec of passes under test to be dumped
pub passes: Vec<String>,
}
@ -14,11 +20,7 @@ pub enum PanicStrategy {
Abort,
}
pub fn output_file_suffix(
testfile: &Path,
bit_width: u32,
panic_strategy: PanicStrategy,
) -> String {
fn output_file_suffix(testfile: &Path, bit_width: u32, panic_strategy: PanicStrategy) -> String {
let mut each_bit_width = false;
let mut each_panic_strategy = false;
for line in fs::read_to_string(testfile).unwrap().lines() {
@ -47,7 +49,7 @@ pub fn files_for_miropt_test(
testfile: &std::path::Path,
bit_width: u32,
panic_strategy: PanicStrategy,
) -> Vec<MiroptTestFiles> {
) -> MiroptTest {
let mut out = Vec::new();
let test_file_contents = fs::read_to_string(&testfile).unwrap();
@ -55,8 +57,14 @@ pub fn files_for_miropt_test(
let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
let suffix = output_file_suffix(testfile, bit_width, panic_strategy);
let mut run_filecheck = true;
let mut passes = Vec::new();
for l in test_file_contents.lines() {
if l.starts_with("// skip-filecheck") {
run_filecheck = false;
continue;
}
if l.starts_with("// EMIT_MIR ") {
let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
let mut test_names = test_name.split(' ');
@ -65,7 +73,6 @@ pub fn files_for_miropt_test(
let mut expected_file;
let from_file;
let to_file;
let mut passes = Vec::new();
if test_name.ends_with(".diff") {
let trimmed = test_name.trim_end_matches(".diff");
@ -114,9 +121,9 @@ pub fn files_for_miropt_test(
}
let expected_file = test_dir.join(expected_file);
out.push(MiroptTestFiles { expected_file, from_file, to_file, passes });
out.push(MiroptTestFile { expected_file, from_file, to_file });
}
}
out
MiroptTest { run_filecheck, suffix, files: out, passes }
}

View File

@ -26,7 +26,8 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) {
for file in rs_files {
for bw in [32, 64] {
for ps in [PanicStrategy::Unwind, PanicStrategy::Abort] {
for output_file in miropt_test_tools::files_for_miropt_test(&file, bw, ps) {
let mir_opt_test = miropt_test_tools::files_for_miropt_test(&file, bw, ps);
for output_file in mir_opt_test.files {
output_files.remove(&output_file.expected_file);
}
}

View File

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

View File

@ -1,36 +1,36 @@
// MIR for `address_of_reborrow` after SimplifyCfg-initial
| User Type Annotations
| 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]
| 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
| 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]
| 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]
| 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]
| 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]
| 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
| 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
| 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]
| 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]
| 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]
| 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
| 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]
| 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]
| 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]
| 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]
| 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
| 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
| 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]
| 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]
| 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]
| 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
| 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]
| 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]
| 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]
| 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]
| 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
| 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
| 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]
| 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]
| 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]
| 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
| 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]
| 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]
| 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]
| 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]
| 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
| 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
| 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]
| 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]
| 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]
| 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
| 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]
| 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]
| 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]
| 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]
| 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
| 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
| 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]
| 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]
| 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]
| 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
| 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]
| 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]
| 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]
| 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]
| 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
| 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
| 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]
| 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]
|
fn address_of_reborrow() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
fn address_of_reborrow() {

View File

@ -1,3 +1,4 @@
// unit-test: SimplifyCfg-elaborate-drops
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Retagging (from Stacked Borrows) relies on the array index being a fresh
// temporary, so that side-effects cannot change it.
@ -11,6 +12,12 @@ unsafe fn foo(z: *mut usize) -> u32 {
// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug x => [[x:_.*]];
// CHECK: debug y => [[y:_.*]];
// CHECK: [[y]] = const 1_usize;
// CHECK: [[tmp:_.*]] = [[y]];
// CHECK: [[x]][[[tmp]]] =
let mut x = [42, 43, 44];
let mut y = 1;
let z: *mut usize = &mut y;

View File

@ -9,6 +9,9 @@
// EMIT_MIR asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
fn main() {
// CHECK-LABEL: fn main(
// CHECK: asm!(
// CHECK-SAME: unwind terminate(abi)
unsafe {
std::arch::asm!("", options(may_unwind));
}

View File

@ -1,8 +1,8 @@
// MIR for `main` after SimplifyCfg-initial
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:20:17: 20:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 1: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:20:17: 20:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 0: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 1: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
fn main() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// unit-test: ElaborateDrops
// needs-unwind
// this tests move up progration, which is not yet implemented
@ -10,6 +11,23 @@
// destruction.
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug nodrop_x => [[nodrop_x:_.*]];
// CHECK: debug nodrop_y => [[nodrop_y:_.*]];
// CHECK: debug drop_x => [[drop_x:_.*]];
// CHECK: debug drop_y => [[drop_y:_.*]];
// CHECK-NOT: drop([[nodrop_x]])
// CHECK-NOT: drop([[nodrop_y]])
// CHECK-NOT: drop([[drop_x]])
// CHECK: [[drop_tmp:_.*]] = move [[drop_x]];
// CHECK-NOT: drop([[drop_x]])
// CHECK-NOT: drop([[drop_tmp]])
// CHECK: [[drop_y]] = move [[drop_tmp]];
// CHECK-NOT: drop([[drop_x]])
// CHECK-NOT: drop([[drop_tmp]])
// CHECK: drop([[drop_y]])
// CHECK-NOT: drop([[drop_x]])
// CHECK-NOT: drop([[drop_tmp]])
let nodrop_x = false;
let nodrop_y;

View File

@ -1,28 +0,0 @@
// unit-test: InstSimplify
// EMIT_MIR bool_compare.opt1.InstSimplify.diff
fn opt1(x: bool) -> u32 {
if x != true { 0 } else { 1 }
}
// EMIT_MIR bool_compare.opt2.InstSimplify.diff
fn opt2(x: bool) -> u32 {
if true != x { 0 } else { 1 }
}
// EMIT_MIR bool_compare.opt3.InstSimplify.diff
fn opt3(x: bool) -> u32 {
if x == false { 0 } else { 1 }
}
// EMIT_MIR bool_compare.opt4.InstSimplify.diff
fn opt4(x: bool) -> u32 {
if false == x { 0 } else { 1 }
}
fn main() {
opt1(false);
opt2(false);
opt3(false);
opt4(false);
}

View File

@ -1,71 +0,0 @@
// MIR for `main` before ElaborateDrops
fn main() -> () {
let mut _0: ();
let _1: std::boxed::Box<S>;
let mut _2: usize;
let mut _3: usize;
let mut _4: *mut u8;
let mut _5: std::boxed::Box<S>;
let _6: ();
let mut _7: std::boxed::Box<S>;
scope 1 {
debug x => _1;
}
scope 2 {
}
bb0: {
StorageLive(_1);
_2 = SizeOf(S);
_3 = AlignOf(S);
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind: bb9];
}
bb1: {
StorageLive(_5);
_5 = ShallowInitBox(move _4, S);
(*_5) = S::new() -> [return: bb2, unwind: bb8];
}
bb2: {
_1 = move _5;
drop(_5) -> [return: bb3, unwind: bb9];
}
bb3: {
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
_7 = move _1;
_6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6];
}
bb4: {
StorageDead(_7);
StorageDead(_6);
_0 = const ();
drop(_1) -> [return: bb5, unwind: bb9];
}
bb5: {
StorageDead(_1);
return;
}
bb6 (cleanup): {
drop(_7) -> [return: bb7, unwind terminate(cleanup)];
}
bb7 (cleanup): {
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
}
bb8 (cleanup): {
drop(_5) -> [return: bb9, unwind terminate(cleanup)];
}
bb9 (cleanup): {
resume;
}
}

View File

@ -1,71 +0,0 @@
// MIR for `main` before ElaborateDrops
fn main() -> () {
let mut _0: ();
let _1: std::boxed::Box<S>;
let mut _2: usize;
let mut _3: usize;
let mut _4: *mut u8;
let mut _5: std::boxed::Box<S>;
let _6: ();
let mut _7: std::boxed::Box<S>;
scope 1 {
debug x => _1;
}
scope 2 {
}
bb0: {
StorageLive(_1);
_2 = SizeOf(S);
_3 = AlignOf(S);
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
}
bb1: {
StorageLive(_5);
_5 = ShallowInitBox(move _4, S);
(*_5) = S::new() -> [return: bb2, unwind: bb8];
}
bb2: {
_1 = move _5;
drop(_5) -> [return: bb3, unwind continue];
}
bb3: {
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
_7 = move _1;
_6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6];
}
bb4: {
StorageDead(_7);
StorageDead(_6);
_0 = const ();
drop(_1) -> [return: bb5, unwind continue];
}
bb5: {
StorageDead(_1);
return;
}
bb6 (cleanup): {
drop(_7) -> [return: bb7, unwind terminate(cleanup)];
}
bb7 (cleanup): {
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
}
bb8 (cleanup): {
drop(_5) -> [return: bb9, unwind terminate(cleanup)];
}
bb9 (cleanup): {
resume;
}
}

View File

@ -0,0 +1,89 @@
- // MIR for `main` before ElaborateDrops
+ // MIR for `main` after ElaborateDrops
fn main() -> () {
let mut _0: ();
let _1: std::boxed::Box<S>;
let mut _2: usize;
let mut _3: usize;
let mut _4: *mut u8;
let mut _5: std::boxed::Box<S>;
let _6: ();
let mut _7: std::boxed::Box<S>;
+ let mut _8: &mut std::boxed::Box<S>;
+ let mut _9: ();
scope 1 {
debug x => _1;
}
scope 2 {
}
bb0: {
StorageLive(_1);
_2 = SizeOf(S);
_3 = AlignOf(S);
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
}
bb1: {
StorageLive(_5);
_5 = ShallowInitBox(move _4, S);
(*_5) = S::new() -> [return: bb2, unwind: bb8];
}
bb2: {
_1 = move _5;
- drop(_5) -> [return: bb3, unwind continue];
+ goto -> bb3;
}
bb3: {
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
_7 = move _1;
_6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6];
}
bb4: {
StorageDead(_7);
StorageDead(_6);
_0 = const ();
- drop(_1) -> [return: bb5, unwind continue];
+ goto -> bb5;
}
bb5: {
StorageDead(_1);
return;
}
bb6 (cleanup): {
- drop(_7) -> [return: bb7, unwind terminate(cleanup)];
+ goto -> bb7;
}
bb7 (cleanup): {
- drop(_1) -> [return: bb9, unwind terminate(cleanup)];
+ goto -> bb9;
}
bb8 (cleanup): {
- drop(_5) -> [return: bb9, unwind terminate(cleanup)];
+ goto -> bb11;
}
bb9 (cleanup): {
resume;
+ }
+
+ bb10 (cleanup): {
+ _8 = &mut _5;
+ _9 = <Box<S> as Drop>::drop(move _8) -> [return: bb9, unwind terminate(cleanup)];
+ }
+
+ bb11 (cleanup): {
+ goto -> bb10;
}
}

View File

@ -1,9 +1,22 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ElaborateDrops
// needs-unwind
#![feature(rustc_attrs, stmt_expr_attributes)]
// EMIT_MIR box_expr.main.ElaborateDrops.before.mir
// EMIT_MIR box_expr.main.ElaborateDrops.diff
fn main() {
// CHECK-LABEL: fn main(
// CHECK: [[box:_.*]] = ShallowInitBox(
// CHECK: [[ptr:_.*]] = ((([[box]].0: std::ptr::Unique<S>).0: std::ptr::NonNull<S>).0: *const S);
// CHECK: (*[[ptr]]) = S::new() -> [return: [[ret:bb.*]], unwind: [[unwind:bb.*]]];
// CHECK: [[ret]]: {
// CHECK: [[box2:_.*]] = move [[box]];
// CHECK: [[box3:_.*]] = move [[box2]];
// CHECK: std::mem::drop::<Box<S>>(move [[box3]])
// CHECK: [[unwind]] (cleanup): {
// CHECK: [[boxref:_.*]] = &mut [[box]];
// CHECK: <Box<S> as Drop>::drop(move [[boxref]])
let x = #[rustc_box]
Box::new(S::new());
drop(x);

View File

@ -9,7 +9,7 @@
storage_conflicts: BitMatrix(0x0) {},
} */
fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>, _2: &mut Context<'_>) -> Poll<()> {
fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _4;
let mut _0: std::task::Poll<()>;
let mut _3: ();
@ -17,7 +17,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>
let mut _5: u32;
bb0: {
_5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16})));
_5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16})));
switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5];
}
@ -29,7 +29,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>
bb2: {
_0 = Poll::<()>::Ready(move _3);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}))) = 1;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}))) = 1;
return;
}

View File

@ -14,7 +14,7 @@
Static,
),
source_info: SourceInfo {
span: $DIR/async_await.rs:15:9: 15:14 (#8),
span: $DIR/async_await.rs:16:9: 16:14 (#8),
scope: scope[0],
},
ignore_for_traits: false,
@ -32,7 +32,7 @@
Static,
),
source_info: SourceInfo {
span: $DIR/async_await.rs:16:9: 16:14 (#10),
span: $DIR/async_await.rs:17:9: 17:14 (#10),
scope: scope[0],
},
ignore_for_traits: false,
@ -51,19 +51,19 @@
},
} */
fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, _2: &mut Context<'_>) -> Poll<()> {
fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _38;
let mut _0: std::task::Poll<()>;
let _3: ();
let mut _4: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _5: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _6: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _4: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _5: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _6: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _7: ();
let _8: ();
let mut _9: std::task::Poll<()>;
let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
let mut _11: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _12: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>;
let mut _11: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _12: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _13: &mut std::task::Context<'_>;
let mut _14: &mut std::task::Context<'_>;
let mut _15: &mut std::task::Context<'_>;
@ -71,14 +71,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
let mut _18: !;
let mut _19: &mut std::task::Context<'_>;
let mut _20: ();
let mut _21: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _22: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _23: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _21: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _22: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _23: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let _24: ();
let mut _25: std::task::Poll<()>;
let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
let mut _27: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _28: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>;
let mut _27: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _28: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _29: &mut std::task::Context<'_>;
let mut _30: &mut std::task::Context<'_>;
let mut _31: &mut std::task::Context<'_>;
@ -90,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
let mut _38: &mut std::task::Context<'_>;
let mut _39: u32;
scope 1 {
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
let _17: ();
scope 2 {
}
@ -99,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
}
scope 4 {
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
let _33: ();
scope 5 {
}
@ -109,7 +109,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
bb0: {
_39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})));
_39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})));
switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30];
}
@ -122,13 +122,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
bb2: {
_4 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
_4 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_5);
nop;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _4;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _4;
goto -> bb4;
}
@ -138,9 +138,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_10);
StorageLive(_11);
StorageLive(_12);
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
_11 = &mut (*_12);
_10 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
_10 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
}
bb5: {
@ -156,7 +156,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
bb6: {
_13 = &mut (*_14);
StorageDead(_15);
_9 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
_9 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
}
bb7: {
@ -176,7 +176,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_20);
_20 = ();
_0 = Poll::<()>::Pending;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2}))) = 3;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3;
return;
}
@ -193,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageDead(_12);
StorageDead(_9);
StorageDead(_8);
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb12, unwind unreachable];
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb12, unwind unreachable];
}
bb11: {
@ -218,13 +218,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
bb14: {
_21 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
_21 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
}
bb15: {
StorageDead(_22);
nop;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _21;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _21;
goto -> bb16;
}
@ -234,9 +234,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_26);
StorageLive(_27);
StorageLive(_28);
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
_27 = &mut (*_28);
_26 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
_26 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
}
bb17: {
@ -252,7 +252,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
bb18: {
_29 = &mut (*_30);
StorageDead(_31);
_25 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
_25 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
}
bb19: {
@ -272,7 +272,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_36);
_36 = ();
_0 = Poll::<()>::Pending;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2}))) = 4;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4;
return;
}
@ -285,7 +285,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageDead(_28);
StorageDead(_25);
StorageDead(_24);
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb23, unwind unreachable];
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb23, unwind unreachable];
}
bb22: {
@ -308,7 +308,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
bb25: {
_0 = Poll::<()>::Ready(move _37);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2}))) = 1;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 1;
return;
}

View File

@ -1,3 +1,4 @@
// skip-filecheck
// This test makes sure that the generator MIR pass eliminates all calls to
// `get_context`, and that the MIR argument type for an async fn and all locals
// related to `yield` are `&mut Context`, and its return type is `Poll`.

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics, inline_const)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics, inline_const)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: --crate-type=lib
#![feature(custom_mir, core_intrinsics, inline_const)]
use std::intrinsics::mir::*;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR enum_cast.foo.built.after.mir
// EMIT_MIR enum_cast.bar.built.after.mir
// EMIT_MIR enum_cast.boo.built.after.mir

View File

@ -1,8 +1,8 @@
// MIR for `main` after built
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
| 1: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
| 0: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
| 1: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
|
fn main() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR issue_101867.main.built.after.mir
fn main() {
let x: Option<u8> = Some(1);

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR issue_110508.{impl#0}-BAR.built.after.mir
// EMIT_MIR issue_110508.{impl#0}-SELF_BAR.built.after.mir

View File

@ -1,6 +1,6 @@
// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR` after built
// MIR for `<impl at $DIR/issue_110508.rs:9:1: 9:9>::BAR` after built
const <impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR: Foo = {
const <impl at $DIR/issue_110508.rs:9:1: 9:9>::BAR: Foo = {
let mut _0: Foo;
let mut _1: ();

View File

@ -1,6 +1,6 @@
// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR` after built
// MIR for `<impl at $DIR/issue_110508.rs:9:1: 9:9>::SELF_BAR` after built
const <impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR: Foo = {
const <impl at $DIR/issue_110508.rs:9:1: 9:9>::SELF_BAR: Foo = {
let mut _0: Foo;
let mut _1: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// We must mark a variable whose initialization fails due to an
// abort statement as StorageDead.

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -Z validate-mir
#![feature(let_chains)]
struct Droppy(u8);

View File

@ -1,3 +1,4 @@
// skip-filecheck
fn guard() -> bool {
false
}

View File

@ -1,10 +1,10 @@
// MIR for `main` after built
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
fn main() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR receiver_ptr_mutability.main.built.after.mir
#![feature(arbitrary_self_types)]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -C debug-assertions=yes
// EMIT_MIR shifts.shift_signed.built.after.mir

View File

@ -1,3 +1,4 @@
// skip-filecheck
// Test that we don't generate unnecessarily large MIR for very simple matches

View File

@ -1,3 +1,4 @@
// skip-filecheck
// Check that when we compile the static `XXX` into MIR, we do not
// generate `StorageStart` or `StorageEnd` statements.

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(stmt_expr_attributes, rustc_attrs)]
// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -Z mir-opt-level=0
// EMIT_MIR byte_slice.main.SimplifyCfg-elaborate-drops.after.mir

View File

@ -1,14 +0,0 @@
// MIR for `redundant` after PreCodegen
fn redundant(_1: *const &u8) -> *const &u8 {
debug x => _1;
let mut _0: *const &u8;
scope 1 (inlined generic_cast::<&u8, &u8>) {
debug x => _1;
}
bb0: {
_0 = _1;
return;
}
}

View File

@ -1,15 +0,0 @@
// MIR for `roundtrip` after PreCodegen
fn roundtrip(_1: *const u8) -> *const u8 {
debug x => _1;
let mut _0: *const u8;
let mut _2: *mut u8;
bb0: {
StorageLive(_2);
_2 = _1 as *mut u8 (PtrToPtr);
_0 = move _2 as *const u8 (PointerCoercion(MutToConstPointer));
StorageDead(_2);
return;
}
}

View File

@ -1,17 +0,0 @@
#![crate_type = "lib"]
// EMIT_MIR casts.redundant.InstSimplify.diff
// EMIT_MIR casts.redundant.PreCodegen.after.mir
pub fn redundant<'a, 'b: 'a>(x: *const &'a u8) -> *const &'a u8 {
generic_cast::<&'a u8, &'b u8>(x) as *const &'a u8
}
#[inline]
fn generic_cast<T, U>(x: *const T) -> *const U {
x as *const U
}
// EMIT_MIR casts.roundtrip.PreCodegen.after.mir
pub fn roundtrip(x: *const u8) -> *const u8 {
x as *mut u8 as *const u8
}

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -C overflow-checks=no -Zunsound-mir-opts
struct Point {

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstGoto
pub enum Foo {

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(min_const_generics)]
#![crate_type = "lib"]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstGoto
// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// ignore-endian-big
extern "C" {
static X: i32;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR address_of_pair.fn0.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -O

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -O -Zmir-opt-level=4

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -O
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR cast.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -C overflow-checks=on

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
#[inline(never)]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Zmir-opt-level=1

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -O

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -C overflow-checks=on

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Zmir-enable-passes=+Inline

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -Zmir-enable-passes=+RemoveZsts
// Verify that we can pretty print invalid constants.

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Z mir-opt-level=3

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Z mir-opt-level=3

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mult_by_zero.test.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mutable_variable.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
static mut STATIC: u32 = 0x42424242;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
static FOO: u8 = 2;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR ref_deref.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR ref_deref_project.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR reify_fn_ptr.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// compile-flags: -C overflow-checks=on

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR scalar_literal_propagation.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Zmir-enable-passes=+InstSimplify

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -Zmir-enable-passes=+SimplifyConstCondition-after-const-prop
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -7,55 +7,77 @@ use std::mem::transmute;
// EMIT_MIR transmute.less_as_i8.ConstProp.diff
pub fn less_as_i8() -> i8 {
// CHECK-LABEL: fn less_as_i8(
// CHECK: _0 = const -1_i8;
unsafe { transmute(std::cmp::Ordering::Less) }
}
// EMIT_MIR transmute.from_char.ConstProp.diff
pub fn from_char() -> i32 {
// CHECK-LABEL: fn from_char(
// CHECK: _0 = const 82_i32;
unsafe { transmute('R') }
}
// EMIT_MIR transmute.valid_char.ConstProp.diff
pub fn valid_char() -> char {
// CHECK-LABEL: fn valid_char(
// CHECK: _0 = const 'R';
unsafe { transmute(0x52_u32) }
}
// EMIT_MIR transmute.invalid_char.ConstProp.diff
pub unsafe fn invalid_char() -> char {
// CHECK-LABEL: fn invalid_char(
// CHECK: _0 = const {transmute(0x7fffffff): char};
unsafe { transmute(i32::MAX) }
}
// EMIT_MIR transmute.invalid_bool.ConstProp.diff
pub unsafe fn invalid_bool() -> bool {
// CHECK-LABEL: fn invalid_bool(
// CHECK: _0 = const {transmute(0xff): bool};
unsafe { transmute(-1_i8) }
}
// EMIT_MIR transmute.undef_union_as_integer.ConstProp.diff
pub unsafe fn undef_union_as_integer() -> u32 {
// CHECK-LABEL: fn undef_union_as_integer(
// CHECK: _1 = Union32 {
// CHECK: _0 = move _1 as u32 (Transmute);
union Union32 { value: u32, unit: () }
unsafe { transmute(Union32 { unit: () }) }
}
// EMIT_MIR transmute.unreachable_direct.ConstProp.diff
pub unsafe fn unreachable_direct() -> ! {
// CHECK-LABEL: fn unreachable_direct(
// CHECK: [[unit:_.*]] = ();
// CHECK: move [[unit]] as Never (Transmute);
let x: Never = unsafe { transmute(()) };
match x {}
}
// EMIT_MIR transmute.unreachable_ref.ConstProp.diff
pub unsafe fn unreachable_ref() -> ! {
// CHECK-LABEL: fn unreachable_ref(
// CHECK: = const {0x1 as &Never};
let x: &Never = unsafe { transmute(1_usize) };
match *x {}
}
// EMIT_MIR transmute.unreachable_mut.ConstProp.diff
pub unsafe fn unreachable_mut() -> ! {
// CHECK-LABEL: fn unreachable_mut(
// CHECK: = const {0x1 as &mut Never};
let x: &mut Never = unsafe { transmute(1_usize) };
match *x {}
}
// EMIT_MIR transmute.unreachable_box.ConstProp.diff
pub unsafe fn unreachable_box() -> ! {
// CHECK-LABEL: fn unreachable_box(
// CHECK: = const Box::<Never>(
let x: Box<Never> = unsafe { transmute(1_usize) };
match *x {}
}

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR tuple_literal_propagation.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR while_let_loops.change_loop_body.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
#![feature(raw_ref_op)]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: CopyProp

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//! Tests that we bail out when there are multiple assignments to the same local.
// unit-test: CopyProp

Some files were not shown because too many files have changed in this diff Show More