Use a better set of targets for blessing mir-opt tests

This commit is contained in:
Ben Kimock 2024-01-07 17:53:20 -05:00
parent 586893c7b0
commit 4451bf4d67
11 changed files with 219 additions and 262 deletions

View File

@ -97,6 +97,20 @@ impl Std {
is_for_mir_opt_tests: false,
}
}
fn copy_extra_objects(
&self,
builder: &Builder<'_>,
compiler: &Compiler,
target: TargetSelection,
) -> Vec<(PathBuf, DependencyType)> {
let mut deps = Vec::new();
if !self.is_for_mir_opt_tests {
deps.extend(copy_third_party_objects(builder, &compiler, target));
deps.extend(copy_self_contained_objects(builder, &compiler, target));
}
deps
}
}
impl Step for Std {
@ -159,8 +173,7 @@ impl Step for Std {
{
builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
copy_third_party_objects(builder, &compiler, target);
copy_self_contained_objects(builder, &compiler, target);
self.copy_extra_objects(builder, &compiler, target);
builder.ensure(StdLink::from_std(self, compiler));
return;
@ -193,15 +206,13 @@ impl Step for Std {
// Even if we're not building std this stage, the new sysroot must
// still contain the third party objects needed by various targets.
copy_third_party_objects(builder, &compiler, target);
copy_self_contained_objects(builder, &compiler, target);
self.copy_extra_objects(builder, &compiler, target);
builder.ensure(StdLink::from_std(self, compiler_to_use));
return;
}
target_deps.extend(copy_third_party_objects(builder, &compiler, target));
target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
// The LLD wrappers and `rust-lld` are self-contained linking components that can be
// necessary to link the stdlib on some targets. We'll also need to copy these binaries to
@ -222,9 +233,12 @@ impl Step for Std {
}
}
// We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
// with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
// fact that this is a check build integrates nicely with run_cargo.
let mut cargo = if self.is_for_mir_opt_tests {
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustc");
cargo.arg("-p").arg("std").arg("--crate-type=lib");
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "check");
cargo.rustflag("-Zalways-encode-mir");
std_cargo(builder, target, compiler.stage, &mut cargo);
cargo
} else {
@ -257,7 +271,7 @@ impl Step for Std {
vec![],
&libstd_stamp(builder, compiler, target),
target_deps,
false,
self.is_for_mir_opt_tests, // is_check
false,
);

View File

@ -25,7 +25,6 @@ use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
use crate::core::config::flags::get_completion;
use crate::core::config::flags::Subcommand;
use crate::core::config::TargetSelection;
use crate::utils;
use crate::utils::cache::{Interned, INTERNER};
use crate::utils::exec::BootstrapCommand;
use crate::utils::helpers::{
@ -38,23 +37,6 @@ use crate::{envify, CLang, DocTests, GitRepo, Mode};
const ADB_TEST_DIR: &str = "/data/local/tmp/work";
// mir-opt tests have different variants depending on whether a target is 32bit or 64bit, and
// blessing them requires blessing with each target. To aid developers, when blessing the mir-opt
// test suite the corresponding target of the opposite pointer size is also blessed.
//
// This array serves as the known mappings between 32bit and 64bit targets. If you're developing on
// a target where a target with the opposite pointer size exists, feel free to add it here.
const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[
// (32bit, 64bit)
("i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"),
("i686-unknown-linux-musl", "x86_64-unknown-linux-musl"),
("i686-pc-windows-msvc", "x86_64-pc-windows-msvc"),
("i686-pc-windows-gnu", "x86_64-pc-windows-gnu"),
// ARM Macs don't have a corresponding 32-bit target that they can (easily)
// build for, so there is no entry for "aarch64-apple-darwin" here.
// Likewise, i686 for macOS is no longer possible to build.
];
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrateBootstrap {
path: Interned<PathBuf>,
@ -1487,46 +1469,19 @@ impl Step for MirOpt {
})
};
// We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants
// (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed.
// When blessing, we try best-effort to also bless the other variants, to aid developers.
if builder.config.cmd.bless() {
let targets = MIR_OPT_BLESS_TARGET_MAPPING
.iter()
.filter(|(target_32bit, target_64bit)| {
*target_32bit == &*self.target.triple || *target_64bit == &*self.target.triple
})
.next()
.map(|(target_32bit, target_64bit)| {
let target_32bit = TargetSelection::from_user(target_32bit);
let target_64bit = TargetSelection::from_user(target_64bit);
crate::utils::cc_detect::find_target(builder, self.compiler.host);
// All that we really need to do is cover all combinations of 32/64-bit and unwind/abort,
// but while we're at it we might as well flex our cross-compilation support. This
// selection covers all our tier 1 operating systems and architectures using only tier
// 1 targets.
// Running compiletest requires a C compiler to be available, but it might not
// have been detected by bootstrap if the target we're testing wasn't in the
// --target flags.
if !builder.cc.borrow().contains_key(&target_32bit) {
utils::cc_detect::find_target(builder, target_32bit);
}
if !builder.cc.borrow().contains_key(&target_64bit) {
utils::cc_detect::find_target(builder, target_64bit);
}
vec![target_32bit, target_64bit]
})
.unwrap_or_else(|| {
eprintln!(
"\
Note that not all variants of mir-opt tests are going to be blessed, as no mapping between
a 32bit and a 64bit target was found for {target}.
You can add that mapping by changing MIR_OPT_BLESS_TARGET_MAPPING in src/bootstrap/test.rs",
target = self.target,
);
vec![self.target]
});
for target in targets {
run(target);
for target in ["aarch64-unknown-linux-gnu", "i686-pc-windows-msvc"] {
run(TargetSelection::from_user(target));
}
for target in ["x86_64-apple-darwin", "i686-unknown-linux-musl"] {
let target = TargetSelection::from_user(target);
let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget {
compiler: self.compiler,
base: target,
@ -1616,27 +1571,27 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
.ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target });
}
if suite == "mir-opt" {
builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
} else {
builder.ensure(compile::Std::new(compiler, target));
}
// Also provide `rust_test_helpers` for the host.
builder.ensure(TestHelpers { target: compiler.host });
// ensure that `libproc_macro` is available on the host.
builder.ensure(compile::Std::new(compiler, compiler.host));
// Also provide `rust_test_helpers` for the host.
builder.ensure(TestHelpers { target: compiler.host });
// As well as the target, except for plain wasm32, which can't build it
if suite != "mir-opt" && !target.contains("wasm") && !target.contains("emscripten") {
builder.ensure(TestHelpers { target });
}
builder.ensure(RemoteCopyLibs { compiler, target });
let mut cmd = builder.tool_cmd(Tool::Compiletest);
if suite == "mir-opt" {
builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
} else {
builder.ensure(compile::Std::new(compiler, target));
}
builder.ensure(RemoteCopyLibs { compiler, target });
// compiletest currently has... a lot of arguments, so let's just pass all
// of them!
@ -1745,11 +1700,13 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
flags.extend(builder.config.cmd.rustc_args().iter().map(|s| s.to_string()));
if let Some(linker) = builder.linker(target) {
cmd.arg("--target-linker").arg(linker);
}
if let Some(linker) = builder.linker(compiler.host) {
cmd.arg("--host-linker").arg(linker);
if suite != "mir-opt" {
if let Some(linker) = builder.linker(target) {
cmd.arg("--target-linker").arg(linker);
}
if let Some(linker) = builder.linker(compiler.host) {
cmd.arg("--host-linker").arg(linker);
}
}
let mut hostflags = flags.clone();
@ -1936,15 +1893,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
}
// Running a C compiler on MSVC requires a few env vars to be set, to be
// sure to set them here.
//
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
// rather than stomp over it.
if !builder.config.dry_run() && target.is_msvc() {
for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
if k != "PATH" {
cmd.env(k, v);
if suite != "mir-opt" {
// Running a C compiler on MSVC requires a few env vars to be set, to be
// sure to set them here.
//
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
// rather than stomp over it.
if !builder.config.dry_run() && target.is_msvc() {
for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
if k != "PATH" {
cmd.env(k, v);
}
}
}
}

View File

@ -1646,76 +1646,12 @@ impl<'a> Builder<'a> {
cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
}
// Dealing with rpath here is a little special, so let's go into some
// detail. First off, `-rpath` is a linker option on Unix platforms
// which adds to the runtime dynamic loader path when looking for
// dynamic libraries. We use this by default on Unix platforms to ensure
// that our nightlies behave the same on Windows, that is they work out
// of the box. This can be disabled by setting `rpath = false` in `[rust]`
// table of `config.toml`
//
// Ok, so the astute might be wondering "why isn't `-C rpath` used
// here?" and that is indeed a good question to ask. This codegen
// option is the compiler's current interface to generating an rpath.
// Unfortunately it doesn't quite suffice for us. The flag currently
// takes no value as an argument, so the compiler calculates what it
// should pass to the linker as `-rpath`. This unfortunately is based on
// the **compile time** directory structure which when building with
// Cargo will be very different than the runtime directory structure.
//
// All that's a really long winded way of saying that if we use
// `-Crpath` then the executables generated have the wrong rpath of
// something like `$ORIGIN/deps` when in fact the way we distribute
// rustc requires the rpath to be `$ORIGIN/../lib`.
//
// So, all in all, to set up the correct rpath we pass the linker
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
// to change a flag in a binary?
if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
let rpath = if target.contains("apple") {
// Note that we need to take one extra step on macOS to also pass
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
// do that we pass a weird flag to the compiler to get it to do
// so. Note that this is definitely a hack, and we should likely
// flesh out rpath support more fully in the future.
rustflags.arg("-Zosx-rpath-install-name");
Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
} else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
rustflags.arg("-Clink-args=-Wl,-z,origin");
Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
} else {
None
};
if let Some(rpath) = rpath {
rustflags.arg(&format!("-Clink-args={rpath}"));
}
}
cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
if let Some(stack_protector) = &self.config.rust_stack_protector {
rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
}
for arg in linker_args(self, compiler.host, LldThreads::Yes) {
hostflags.arg(&arg);
}
if let Some(target_linker) = self.linker(target) {
let target = crate::envify(&target.triple);
cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
}
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
// `linker_args` here.
for flag in linker_flags(self, target, LldThreads::Yes) {
rustflags.arg(&flag);
}
for arg in linker_args(self, target, LldThreads::Yes) {
rustdocflags.arg(&arg);
}
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
}
@ -1731,10 +1667,6 @@ impl<'a> Builder<'a> {
if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() {
cargo.env(profile_var("OPT_LEVEL"), opt_level);
}
if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
{
rustflags.arg("-Clink-arg=-gz");
}
cargo.env(
profile_var("DEBUG_ASSERTIONS"),
if mode == Mode::Std {
@ -1940,55 +1872,15 @@ impl<'a> Builder<'a> {
rustflags.arg("-Wrustc::internal");
}
// Throughout the build Cargo can execute a number of build scripts
// compiling C/C++ code and we need to pass compilers, archivers, flags, etc
// obtained previously to those build scripts.
// Build scripts use either the `cc` crate or `configure/make` so we pass
// the options through environment variables that are fetched and understood by both.
//
// FIXME: the guard against msvc shouldn't need to be here
if target.is_msvc() {
if let Some(ref cl) = self.config.llvm_clang_cl {
cargo.env("CC", cl).env("CXX", cl);
}
} else {
let ccache = self.config.ccache.as_ref();
let ccacheify = |s: &Path| {
let ccache = match ccache {
Some(ref s) => s,
None => return s.display().to_string(),
};
// FIXME: the cc-rs crate only recognizes the literal strings
// `ccache` and `sccache` when doing caching compilations, so we
// mirror that here. It should probably be fixed upstream to
// accept a new env var or otherwise work with custom ccache
// vars.
match &ccache[..] {
"ccache" | "sccache" => format!("{} {}", ccache, s.display()),
_ => s.display().to_string(),
}
};
let triple_underscored = target.triple.replace("-", "_");
let cc = ccacheify(&self.cc(target));
cargo.env(format!("CC_{triple_underscored}"), &cc);
let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
if let Some(ar) = self.ar(target) {
let ranlib = format!("{} s", ar.display());
cargo
.env(format!("AR_{triple_underscored}"), ar)
.env(format!("RANLIB_{triple_underscored}"), ranlib);
}
if let Ok(cxx) = self.cxx(target) {
let cxx = ccacheify(&cxx);
let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
cargo
.env(format!("CXX_{triple_underscored}"), &cxx)
.env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
}
if cmd != "check" {
self.configure_linker(
compiler,
target,
&mut cargo,
&mut rustflags,
&mut rustdocflags,
&mut hostflags,
);
}
// If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
@ -2142,6 +2034,136 @@ impl<'a> Builder<'a> {
Cargo { command: cargo, rustflags, rustdocflags, hostflags, allow_features }
}
fn configure_linker(
&self,
compiler: Compiler,
target: TargetSelection,
cargo: &mut Command,
rustflags: &mut Rustflags,
rustdocflags: &mut Rustflags,
hostflags: &mut HostFlags,
) {
// Dealing with rpath here is a little special, so let's go into some
// detail. First off, `-rpath` is a linker option on Unix platforms
// which adds to the runtime dynamic loader path when looking for
// dynamic libraries. We use this by default on Unix platforms to ensure
// that our nightlies behave the same on Windows, that is they work out
// of the box. This can be disabled by setting `rpath = false` in `[rust]`
// table of `config.toml`
//
// Ok, so the astute might be wondering "why isn't `-C rpath` used
// here?" and that is indeed a good question to ask. This codegen
// option is the compiler's current interface to generating an rpath.
// Unfortunately it doesn't quite suffice for us. The flag currently
// takes no value as an argument, so the compiler calculates what it
// should pass to the linker as `-rpath`. This unfortunately is based on
// the **compile time** directory structure which when building with
// Cargo will be very different than the runtime directory structure.
//
// All that's a really long winded way of saying that if we use
// `-Crpath` then the executables generated have the wrong rpath of
// something like `$ORIGIN/deps` when in fact the way we distribute
// rustc requires the rpath to be `$ORIGIN/../lib`.
//
// So, all in all, to set up the correct rpath we pass the linker
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
// to change a flag in a binary?
if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
let rpath = if target.contains("apple") {
// Note that we need to take one extra step on macOS to also pass
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
// do that we pass a weird flag to the compiler to get it to do
// so. Note that this is definitely a hack, and we should likely
// flesh out rpath support more fully in the future.
rustflags.arg("-Zosx-rpath-install-name");
Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
} else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
rustflags.arg("-Clink-args=-Wl,-z,origin");
Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
} else {
None
};
if let Some(rpath) = rpath {
rustflags.arg(&format!("-Clink-args={rpath}"));
}
}
for arg in linker_args(self, compiler.host, LldThreads::Yes) {
hostflags.arg(&arg);
}
if let Some(target_linker) = self.linker(target) {
let target = crate::envify(&target.triple);
cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
}
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
// `linker_args` here.
for flag in linker_flags(self, target, LldThreads::Yes) {
rustflags.arg(&flag);
}
for arg in linker_args(self, target, LldThreads::Yes) {
rustdocflags.arg(&arg);
}
if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
{
rustflags.arg("-Clink-arg=-gz");
}
// Throughout the build Cargo can execute a number of build scripts
// compiling C/C++ code and we need to pass compilers, archivers, flags, etc
// obtained previously to those build scripts.
// Build scripts use either the `cc` crate or `configure/make` so we pass
// the options through environment variables that are fetched and understood by both.
//
// FIXME: the guard against msvc shouldn't need to be here
if target.is_msvc() {
if let Some(ref cl) = self.config.llvm_clang_cl {
cargo.env("CC", cl).env("CXX", cl);
}
} else {
let ccache = self.config.ccache.as_ref();
let ccacheify = |s: &Path| {
let ccache = match ccache {
Some(ref s) => s,
None => return s.display().to_string(),
};
// FIXME: the cc-rs crate only recognizes the literal strings
// `ccache` and `sccache` when doing caching compilations, so we
// mirror that here. It should probably be fixed upstream to
// accept a new env var or otherwise work with custom ccache
// vars.
match &ccache[..] {
"ccache" | "sccache" => format!("{} {}", ccache, s.display()),
_ => s.display().to_string(),
}
};
let triple_underscored = target.triple.replace("-", "_");
let cc = ccacheify(&self.cc(target));
cargo.env(format!("CC_{triple_underscored}"), &cc);
let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
if let Some(ar) = self.ar(target) {
let ranlib = format!("{} s", ar.display());
cargo
.env(format!("AR_{triple_underscored}"), ar)
.env(format!("RANLIB_{triple_underscored}"), ranlib);
}
if let Ok(cxx) = self.cxx(target) {
let cxx = ccacheify(&cxx);
let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
cargo
.env(format!("CXX_{triple_underscored}"), &cxx)
.env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
}
}
}
/// Ensure that a given step is built, returning its output. This will
/// cache the step, so it is safe (and good!) to call this as often as
/// needed to ensure that all dependencies are built.

View File

@ -2467,6 +2467,8 @@ impl<'test> TestCx<'test> {
"-Zvalidate-mir",
"-Zlint-mir",
"-Zdump-mir-exclude-pass-number",
"--crate-type=rlib",
"-Clink-dead-code",
]);
if let Some(pass) = &self.props.mir_unit_test {
rustc.args(&["-Zmir-opt-level=0", &format!("-Zmir-enable-passes=+{}", pass)]);

View File

@ -4,35 +4,16 @@
fn g() -> () {
let mut _0: ();
let _1: ();
+ let mut _2: fn() {main};
+ scope 1 (inlined f::<fn() {main}>) {
+ debug g => _2;
+ let mut _3: &fn() {main};
+ let _4: ();
+ }
bb0: {
StorageLive(_1);
- _1 = f::<fn() {main}>(main) -> [return: bb1, unwind unreachable];
+ StorageLive(_2);
+ _2 = main;
+ StorageLive(_4);
+ StorageLive(_3);
+ _3 = &_2;
+ _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind unreachable];
_1 = f::<fn() {main}>(main) -> [return: bb1, unwind unreachable];
}
bb1: {
+ StorageDead(_4);
+ StorageDead(_2);
StorageDead(_1);
_0 = const ();
return;
+ }
+
+ bb2: {
+ StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind unreachable];
}
}

View File

@ -4,43 +4,16 @@
fn g() -> () {
let mut _0: ();
let _1: ();
+ let mut _2: fn() {main};
+ scope 1 (inlined f::<fn() {main}>) {
+ debug g => _2;
+ let mut _3: &fn() {main};
+ let _4: ();
+ }
bb0: {
StorageLive(_1);
- _1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
+ StorageLive(_2);
+ _2 = main;
+ StorageLive(_4);
+ StorageLive(_3);
+ _3 = &_2;
+ _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind: bb3];
_1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
}
bb1: {
+ StorageDead(_4);
+ StorageDead(_2);
StorageDead(_1);
_0 = const ();
return;
+ }
+
+ bb2: {
+ StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind continue];
+ }
+
+ bb3 (cleanup): {
+ drop(_2) -> [return: bb4, unwind terminate(cleanup)];
+ }
+
+ bb4 (cleanup): {
+ resume;
}
}

View File

@ -13,9 +13,7 @@ fn f(g: impl Fn()) {
#[inline(always)]
fn g() {
// CHECK-LABEL: fn g(
// CHECK-NOT: inlined
// CHECK: (inlined f::<fn() {main}>)
// CHECK-NOT: inlined
// CHECK-NOT: (inlined f::<fn() {main}>)
f(main);
}

View File

@ -7,6 +7,10 @@
+ scope 1 (inlined <C as Call>::call) {
+ scope 2 (inlined <B<A> as Call>::call) {
+ scope 3 (inlined <A as Call>::call) {
+ scope 4 (inlined <B<C> as Call>::call) {
+ scope 5 (inlined <C as Call>::call) {
+ }
+ }
+ }
+ }
+ }
@ -14,7 +18,7 @@
bb0: {
StorageLive(_1);
- _1 = <C as Call>::call() -> [return: bb1, unwind unreachable];
+ _1 = <B<C> as Call>::call() -> [return: bb1, unwind unreachable];
+ _1 = <B<A> as Call>::call() -> [return: bb1, unwind unreachable];
}
bb1: {

View File

@ -7,6 +7,10 @@
+ scope 1 (inlined <C as Call>::call) {
+ scope 2 (inlined <B<A> as Call>::call) {
+ scope 3 (inlined <A as Call>::call) {
+ scope 4 (inlined <B<C> as Call>::call) {
+ scope 5 (inlined <C as Call>::call) {
+ }
+ }
+ }
+ }
+ }
@ -14,7 +18,7 @@
bb0: {
StorageLive(_1);
- _1 = <C as Call>::call() -> [return: bb1, unwind continue];
+ _1 = <B<C> as Call>::call() -> [return: bb1, unwind continue];
+ _1 = <B<A> as Call>::call() -> [return: bb1, unwind continue];
}
bb1: {

View File

@ -1,8 +1,8 @@
// MIR for `main` after built
| User Type Annotations
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
fn main() -> () {
let mut _0: ();

View File

@ -1,8 +1,8 @@
// MIR for `main` after built
| User Type Annotations
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
fn main() -> () {
let mut _0: ();