Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 2 additions & 37 deletions cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
assert_eq!(val, "metadata");
} else {
// For all other kinds of tests, we can just add our flag.
cmd.arg("--emit=metadata");
cmd.arg("--emit=metadata,link");
}

// Alter the `-o` parameter so that it does not overwrite the JSON file we stored above.
Expand Down Expand Up @@ -444,7 +444,6 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
}

let mut cmd = miri();
let mut emit_link_hack = false;
// Arguments are treated very differently depending on whether this crate is
// for interpretation by Miri, or for use by a build script / proc macro.
if target_crate {
Expand All @@ -455,7 +454,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
}

// Forward arguments, but patched.
let emit_flag = "--emit";

// This hack helps bootstrap run standard library tests in Miri. The issue is as follows:
// when running `cargo miri test` on libcore, cargo builds a local copy of core and makes it
// a dependency of the integration test crate. This copy duplicates all the lang items, so
Expand All @@ -472,29 +471,6 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
&& !runnable_crate
&& phase == RustcPhase::Build;
while let Some(arg) = args.next() {
// Patch `--emit`: remove "link" from "--emit" to make this a check-only build.
if let Some(val) = arg.strip_prefix(emit_flag) {
// Patch this argument. First, extract its value.
let val =
val.strip_prefix('=').expect("`cargo` should pass `--emit=X` as one argument");
let mut val: Vec<_> = val.split(',').collect();
// Now make sure "link" is not in there, but "metadata" is.
if let Some(i) = val.iter().position(|&s| s == "link") {
emit_link_hack = true;
val.remove(i);
if !val.contains(&"metadata") {
val.push("metadata");
}
}
cmd.arg(format!("{emit_flag}={}", val.join(",")));
continue;
}
// Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
// https://github.com/rust-lang/miri/issues/1705
if arg == "--extern" {
forward_patched_extern_arg(&mut args, &mut cmd);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The forward_patched_extern_arg function can likely be removed as the fake lib file hack has been removed.

continue;
}
// If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a
// `lib.miri.rs` file exists, then build that instead.
if replace_librs {
Expand Down Expand Up @@ -543,17 +519,6 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
eprintln!("[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate}");
}

// Create a stub .rlib file if "link" was requested by cargo.
// This is necessary to prevent cargo from doing rebuilds all the time.
if emit_link_hack {
for filename in out_filenames() {
if verbose > 0 {
eprintln!("[cargo-miri rustc] creating fake lib file at `{}`", filename.display());
}
File::create(filename).expect("failed to create fake lib file");
}
}

debug_cmd("[cargo-miri rustc]", verbose, &cmd);
exec(cmd);
}
Expand Down
2 changes: 1 addition & 1 deletion cargo-miri/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub fn setup(

// Do the build.
let status = SysrootBuilder::new(&sysroot_dir, target)
.build_mode(BuildMode::Check)
.build_mode(BuildMode::Build)
.rustc_version(rustc_version.clone())
.sysroot_config(sysroot_config)
.rustflags(rustflags)
Expand Down
73 changes: 2 additions & 71 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,12 @@ use miri::{
use rustc_abi::ExternAbi;
use rustc_data_structures::sync;
use rustc_driver::Compilation;
use rustc_hir as hir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_hir::{self as hir, Node};
use rustc_hir_analysis::check::check_function_signature;
use rustc_interface::interface::Config;
use rustc_log::tracing::debug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{
ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
};
use rustc_middle::query::LocalCrate;
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util::Providers;
Expand Down Expand Up @@ -250,71 +246,6 @@ struct MiriBeRustCompilerCalls {
}

impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
#[allow(rustc::potential_query_instability)] // rustc_codegen_ssa (where this code is copied from) also allows this lint
fn config(&mut self, config: &mut Config) {
if config.opts.prints.is_empty() && self.target_crate {
// Queries overridden here affect the data stored in `rmeta` files of dependencies,
// which will be used later in non-`MIRI_BE_RUSTC` mode.
config.override_queries = Some(|_, local_providers| {
// `exported_non_generic_symbols` and `reachable_non_generics` provided by rustc always returns
// an empty result if `tcx.sess.opts.output_types.should_codegen()` is false.
// In addition we need to add #[used] symbols to exported_symbols for `lookup_link_section`.
local_providers.exported_non_generic_symbols = |tcx, LocalCrate| {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought we may still need this for #[used].

let reachable_set = tcx.with_stable_hashing_context(|hcx| {
tcx.reachable_set(()).to_sorted(&hcx, true)
});
tcx.arena.alloc_from_iter(
// This is based on:
// https://github.com/rust-lang/rust/blob/2962e7c0089d5c136f4e9600b7abccfbbde4973d/compiler/rustc_codegen_ssa/src/back/symbol_export.rs#L62-L63
// https://github.com/rust-lang/rust/blob/2962e7c0089d5c136f4e9600b7abccfbbde4973d/compiler/rustc_codegen_ssa/src/back/symbol_export.rs#L174
reachable_set.into_iter().filter_map(|&local_def_id| {
// Do the same filtering that rustc does:
// https://github.com/rust-lang/rust/blob/2962e7c0089d5c136f4e9600b7abccfbbde4973d/compiler/rustc_codegen_ssa/src/back/symbol_export.rs#L84-L102
// Otherwise it may cause unexpected behaviours and ICEs
// (https://github.com/rust-lang/rust/issues/86261).
let is_reachable_non_generic = matches!(
tcx.hir_node_by_def_id(local_def_id),
Node::Item(&hir::Item {
kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn{ .. },
..
}) | Node::ImplItem(&hir::ImplItem {
kind: hir::ImplItemKind::Fn(..),
..
})
if !tcx.generics_of(local_def_id).requires_monomorphization(tcx)
);
if !is_reachable_non_generic {
return None;
}
let codegen_fn_attrs = tcx.codegen_fn_attrs(local_def_id);
if codegen_fn_attrs.contains_extern_indicator()
|| codegen_fn_attrs
.flags
.contains(CodegenFnAttrFlags::USED_COMPILER)
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
{
Some((
ExportedSymbol::NonGeneric(local_def_id.to_def_id()),
// Some dummy `SymbolExportInfo` here. We only use
// `exported_symbols` in shims/foreign_items.rs and the export info
// is ignored.
SymbolExportInfo {
level: SymbolExportLevel::C,
kind: SymbolExportKind::Text,
used: false,
rustc_std_internal_symbol: false,
},
))
} else {
None
}
}),
)
}
});
}
}

fn after_analysis<'tcx>(
&mut self,
_: &rustc_interface::interface::Compiler,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ pub use crate::shims::unwind::{CatchUnwindData, EvalContextExt as _};
/// Also disable the MIR pass that inserts an alignment check on every pointer dereference. Miri
/// does that too, and with a better error message.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
"-Zcodegen-backend=dummy",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dummy codegen backend is a builtin codegen backend that is only capable of emitting rlibs containing the crate metadata. For every other crate type it emits an error after codegen. This is fine for miri as for --crate-type bin, miri exits before codegen.

"--cfg=miri",
"-Zalways-encode-mir",
"-Zextra-const-ub-checks",
Expand Down
Loading