Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
14795f0
slightly extend PR creation message
RalfJung Nov 5, 2025
4384d43
Prepare for merging from rust-lang/rust
Nov 6, 2025
bca4136
Merge ref '401ae5542752' from rust-lang/rust
Nov 6, 2025
3d08696
fmt
Nov 6, 2025
29c28b3
Merge pull request #4671 from rust-lang/rustup-2025-11-06
RalfJung Nov 6, 2025
6b394d4
Merge pull request #4669 from RalfJung/triagebot-welcome
RalfJung Nov 6, 2025
8d597aa
Remove implementation of LLVM SIMD intrinsics that are not needed any…
eduardosm Nov 4, 2025
2760570
Merge pull request #4667 from eduardosm/remove-intrinsics
RalfJung Nov 6, 2025
d59e58b
Use the dummy codegen backend
bjorn3 Oct 23, 2025
ccdb1c0
Merge pull request #4648 from bjorn3/dummy_backend
RalfJung Nov 6, 2025
7711eb9
lazy_sync: ensure the cookie fits inside the primitive
RalfJung Nov 6, 2025
b8eee76
./miri run: verbose by default, add flag to be quiet
RalfJung Nov 4, 2025
384c05f
fix 'cargo miri setup' quietness
RalfJung Nov 7, 2025
4ddc3ad
Merge pull request #4665 from RalfJung/run-verbose
RalfJung Nov 7, 2025
f6b751e
Prepare for merging from rust-lang/rust
Nov 8, 2025
c7da7c3
Merge ref 'ceb7df7e6f17' from rust-lang/rust
Nov 8, 2025
f796155
Merge pull request #4673 from rust-lang/rustup-2025-11-08
oli-obk Nov 8, 2025
edc13e6
pthread: replace INIT_COOKIE by sync object metadata that gets cleare…
RalfJung Nov 6, 2025
ba789c6
also use new sync obj metadata scheme for INIT_ONCE and os_unfair_lock
RalfJung Nov 7, 2025
155b09f
throw an error if a synchronization object is read/written while thre…
RalfJung Nov 7, 2025
3c4b29c
remove dead code
RalfJung Nov 7, 2025
d6b01ab
also inform sync objcts about deallocation; needs separate AccessKind…
RalfJung Nov 8, 2025
e14780a
Merge pull request #4672 from RalfJung/sync-objs
RalfJung Nov 8, 2025
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
77 changes: 8 additions & 69 deletions src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,6 @@ fn show_version() {
println!();
}

fn forward_patched_extern_arg(args: &mut impl Iterator<Item = String>, cmd: &mut Command) {
cmd.arg("--extern"); // always forward flag, but adjust filename:
let path = args.next().expect("`--extern` should be followed by a filename");
if let Some(lib) = path.strip_suffix(".rlib") {
// If this is an rlib, make it an rmeta.
cmd.arg(format!("{lib}.rmeta"));
} else {
// Some other extern file (e.g. a `.so`). Forward unchanged.
cmd.arg(path);
}
}

pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
// Require a subcommand before any flags.
// We cannot know which of those flags take arguments and which do not,
Expand Down Expand Up @@ -276,7 +264,7 @@ pub enum RustcPhase {
Rustdoc,
}

pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
pub fn phase_rustc(args: impl Iterator<Item = String>, phase: RustcPhase) {
/// Determines if we are being invoked (as rustc) to build a crate for
/// the "target" architecture, in contrast to the "host" architecture.
/// Host crates are for build scripts and proc macros and still need to
Expand Down Expand Up @@ -444,7 +432,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 +442,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 @@ -471,30 +458,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
let replace_librs = env::var_os("MIRI_REPLACE_LIBRS_IF_NOT_TEST").is_some()
&& !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);
continue;
}
for arg in args {
// 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 +507,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 Expand Up @@ -624,17 +577,11 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap());
}
// Forward rustc arguments.
// We need to patch "--extern" filenames because we forced a check-only
// build without cargo knowing about that: replace `.rlib` suffix by
// `.rmeta`.
// We also need to remove `--error-format` as cargo specifies that to be JSON,
// We need to remove `--error-format` as cargo specifies that to be JSON,
// but when we run here, cargo does not interpret the JSON any more. `--json`
// then also needs to be dropped.
let mut args = info.args.iter();
while let Some(arg) = args.next() {
if arg == "--extern" {
forward_patched_extern_arg(&mut (&mut args).cloned(), &mut cmd);
} else if let Some(suffix) = arg.strip_prefix("--error-format") {
for arg in &info.args {
if let Some(suffix) = arg.strip_prefix("--error-format") {
assert!(suffix.starts_with('='));
// Drop this argument.
} else if let Some(suffix) = arg.strip_prefix("--json") {
Expand Down Expand Up @@ -668,23 +615,15 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
}
}

pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
pub fn phase_rustdoc(args: impl Iterator<Item = String>) {
let verbose = env::var("MIRI_VERBOSE")
.map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer"));

// phase_cargo_miri sets the RUSTDOC env var to ourselves, and puts a backup
// of the old value into MIRI_ORIG_RUSTDOC. So that's what we have to invoke now.
let rustdoc = env::var("MIRI_ORIG_RUSTDOC").unwrap_or("rustdoc".to_string());
let mut cmd = Command::new(rustdoc);

while let Some(arg) = args.next() {
if arg == "--extern" {
// Patch --extern arguments to use *.rmeta files, since phase_cargo_rustc only creates stub *.rlib files.
forward_patched_extern_arg(&mut args, &mut cmd);
} else {
cmd.arg(arg);
}
}
cmd.args(args);

// Doctests of `proc-macro` crates (and their dependencies) are always built for the host,
// so we are not able to run them in Miri.
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/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) // not a real build, since we use dummy codegen
.rustc_version(rustc_version.clone())
.sysroot_config(sysroot_config)
.rustflags(rustflags)
Expand Down
16 changes: 9 additions & 7 deletions src/tools/miri/miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ impl MiriEnv {
.arg("--")
.args(&["miri", "setup", "--print-sysroot"])
.args(target_flag);
cmd.set_quiet(quiet);
if quiet {
cmd = cmd.arg("--quiet");
}
let output = cmd.read()?;
self.sh.set_var("MIRI_SYSROOT", &output);
Ok(output.into())
Expand Down Expand Up @@ -112,8 +114,8 @@ impl Command {
Command::Check { features, flags } => Self::check(features, flags),
Command::Test { bless, target, coverage, features, flags } =>
Self::test(bless, target, coverage, features, flags),
Command::Run { dep, verbose, target, edition, features, flags } =>
Self::run(dep, verbose, target, edition, features, flags),
Command::Run { dep, quiet, target, edition, features, flags } =>
Self::run(dep, quiet, target, edition, features, flags),
Command::Doc { features, flags } => Self::doc(features, flags),
Command::Fmt { flags } => Self::fmt(flags),
Command::Clippy { features, flags } => Self::clippy(features, flags),
Expand Down Expand Up @@ -458,7 +460,7 @@ impl Command {

fn run(
dep: bool,
verbose: bool,
quiet: bool,
target: Option<String>,
edition: Option<String>,
features: Vec<String>,
Expand All @@ -468,7 +470,7 @@ impl Command {

// Preparation: get a sysroot, and get the miri binary.
let miri_sysroot =
e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref(), &features)?;
e.build_miri_sysroot(/* quiet */ quiet, target.as_deref(), &features)?;
let miri_bin = e
.build_get_binary(".", &features)
.context("failed to get filename of miri executable")?;
Expand All @@ -492,7 +494,7 @@ impl Command {
// Compute flags.
let miri_flags = e.sh.var("MIRIFLAGS").unwrap_or_default();
let miri_flags = flagsplit(&miri_flags);
let quiet_flag = if verbose { None } else { Some("--quiet") };
let quiet_flag = if quiet { Some("--quiet") } else { None };

// Run Miri.
// The basic command that executes the Miri driver.
Expand All @@ -506,7 +508,7 @@ impl Command {
} else {
cmd!(e.sh, "{miri_bin}")
};
cmd.set_quiet(!verbose);
cmd.set_quiet(quiet);
// Add Miri flags
let mut cmd = cmd.args(&miri_flags).args(&early_flags).args(&flags);
// For `--dep` we also need to set the target in the env var.
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/miri-script/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ pub enum Command {
/// Build the program with the dependencies declared in `tests/deps/Cargo.toml`.
#[arg(long)]
dep: bool,
/// Show build progress.
/// Hide build progress.
#[arg(long, short)]
verbose: bool,
quiet: bool,
/// The cross-interpretation target.
#[arg(long)]
target: Option<String>,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5f9dd05862d2e4bceb3be1031b6c936e35671501
ceb7df7e6f17c92c7d49f7e4f02df0e68bc9b38b
40 changes: 17 additions & 23 deletions src/tools/miri/src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ extern crate rustc_hir;
extern crate rustc_hir_analysis;
extern crate rustc_interface;
extern crate rustc_log;
extern crate rustc_metadata;
extern crate rustc_middle;
extern crate rustc_session;
extern crate rustc_span;
Expand All @@ -26,10 +25,8 @@ mod log;
use std::env;
use std::num::NonZero;
use std::ops::Range;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};

use miri::{
Expand All @@ -51,10 +48,8 @@ use rustc_middle::middle::exported_symbols::{
use rustc_middle::query::LocalCrate;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util::Providers;
use rustc_session::EarlyDiagCtxt;
use rustc_session::config::{CrateType, ErrorOutputType, OptLevel};
use rustc_session::search_paths::PathKind;
use rustc_span::def_id::DefId;

use crate::log::setup::{deinit_loggers, init_early_loggers, init_late_loggers};
Expand Down Expand Up @@ -126,21 +121,6 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
}

impl rustc_driver::Callbacks for MiriCompilerCalls {
fn config(&mut self, config: &mut Config) {
config.override_queries = Some(|_, providers| {
providers.extern_queries.used_crate_source = |tcx, cnum| {
let mut providers = Providers::default();
rustc_metadata::provide(&mut providers);
let mut crate_source = (providers.extern_queries.used_crate_source)(tcx, cnum);
// HACK: rustc will emit "crate ... required to be available in rlib format, but
// was not found in this form" errors once we use `tcx.dependency_formats()` if
// there's no rlib provided, so setting a dummy path here to workaround those errors.
Arc::make_mut(&mut crate_source).rlib = Some((PathBuf::new(), PathKind::All));
crate_source
};
});
}

fn after_analysis<'tcx>(
&mut self,
_: &rustc_interface::interface::Compiler,
Expand Down Expand Up @@ -253,12 +233,26 @@ 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 {
#[allow(rustc::bad_opt_access)] // tcx does not exist yet
{
let any_crate_types = !config.opts.crate_types.is_empty();
// Avoid warnings about unsupported crate types.
config
.opts
.crate_types
.retain(|&c| c == CrateType::Executable || c == CrateType::Rlib);
if any_crate_types {
// Assert that we didn't remove all crate types if any crate type was passed on
// the cli. Otherwise we might silently change what kind of crate we are building.
assert!(!config.opts.crate_types.is_empty());
}
}

// 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`.
// We need to add #[used] symbols to exported_symbols for `lookup_link_section`.
// FIXME handle this somehow in rustc itself to avoid this hack.
local_providers.exported_non_generic_symbols = |tcx, LocalCrate| {
let reachable_set = tcx.with_stable_hashing_context(|hcx| {
tcx.reachable_set(()).to_sorted(&hcx, true)
Expand Down
25 changes: 16 additions & 9 deletions src/tools/miri/src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ use crate::*;
pub mod stacked_borrows;
pub mod tree_borrows;

/// Indicates which kind of access is being performed.
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
pub enum AccessKind {
Read,
Write,
}

impl fmt::Display for AccessKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AccessKind::Read => write!(f, "read access"),
AccessKind::Write => write!(f, "write access"),
}
}
}

/// Tracking pointer provenance
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct BorTag(NonZero<u64>);
Expand Down Expand Up @@ -115,15 +131,6 @@ impl VisitProvenance for GlobalStateInner {
/// We need interior mutable access to the global state.
pub type GlobalState = RefCell<GlobalStateInner>;

impl fmt::Display for AccessKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AccessKind::Read => write!(f, "read access"),
AccessKind::Write => write!(f, "write access"),
}
}
}

/// Policy on whether to recurse into fields to retag
#[derive(Copy, Clone, Debug)]
pub enum RetagFields {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_span::{Span, SpanData};
use smallvec::SmallVec;

use crate::borrow_tracker::{GlobalStateInner, ProtectorKind};
use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind};
use crate::*;

/// Error reporting
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use self::stack::Stack;
use crate::borrow_tracker::stacked_borrows::diagnostics::{
AllocHistory, DiagnosticCx, DiagnosticCxBuilder,
};
use crate::borrow_tracker::{GlobalStateInner, ProtectorKind};
use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind};
use crate::concurrency::data_race::{NaReadType, NaWriteType};
use crate::*;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use std::ops::Range;
use rustc_data_structures::fx::FxHashMap;
use rustc_span::{Span, SpanData};

use crate::borrow_tracker::ProtectorKind;
use crate::borrow_tracker::tree_borrows::perms::{PermTransition, Permission};
use crate::borrow_tracker::tree_borrows::tree::LocationState;
use crate::borrow_tracker::tree_borrows::unimap::UniIndex;
use crate::borrow_tracker::{AccessKind, ProtectorKind};
use crate::*;

/// Cause of an access: either a real access or one
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_middle::ty::{self, Ty};

use self::foreign_access_skipping::IdempotentForeignAccess;
use self::tree::LocationState;
use crate::borrow_tracker::{GlobalState, GlobalStateInner, ProtectorKind};
use crate::borrow_tracker::{AccessKind, GlobalState, GlobalStateInner, ProtectorKind};
use crate::concurrency::data_race::NaReadType;
use crate::*;

Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::cmp::{Ordering, PartialOrd};
use std::fmt;

use crate::AccessKind;
use crate::borrow_tracker::AccessKind;
use crate::borrow_tracker::tree_borrows::diagnostics::TransitionError;
use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness;

Expand Down
Loading
Loading