Skip to content

miri: for ABI mismatch errors, say which argument is the problem #144535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 28, 2025
Merged
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
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,15 @@ const_eval_frame_note_inner = inside {$where_ ->
const_eval_frame_note_last = the failure occurred here
const_eval_incompatible_arg_types =
calling a function whose parameter #{$arg_idx} has type {$callee_ty} passing argument of type {$caller_ty}
const_eval_incompatible_calling_conventions =
calling a function with calling convention "{$callee_conv}" using calling convention "{$caller_conv}"
const_eval_incompatible_return_types =
calling a function with return type {$callee_ty} passing return place of type {$caller_ty}
const_eval_incompatible_types =
calling a function with argument of type {$callee_ty} passing data of type {$caller_ty}
const_eval_interior_mutable_borrow_escaping =
interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed
.label = this borrow of an interior mutable value refers to such a temporary
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
InvalidNichedEnumVariantWritten { .. } => {
const_eval_invalid_niched_enum_variant_written
}
AbiMismatchArgument { .. } => const_eval_incompatible_types,
AbiMismatchArgument { .. } => const_eval_incompatible_arg_types,
AbiMismatchReturn { .. } => const_eval_incompatible_return_types,
}
}
Expand Down Expand Up @@ -625,12 +625,16 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
diag.arg("data_size", info.data_size);
}
InvalidNichedEnumVariantWritten { enum_ty } => {
diag.arg("ty", enum_ty.to_string());
diag.arg("ty", enum_ty);
}
AbiMismatchArgument { caller_ty, callee_ty }
| AbiMismatchReturn { caller_ty, callee_ty } => {
diag.arg("caller_ty", caller_ty.to_string());
diag.arg("callee_ty", callee_ty.to_string());
AbiMismatchArgument { arg_idx, caller_ty, callee_ty } => {
diag.arg("arg_idx", arg_idx + 1); // adjust for 1-indexed lists in output
diag.arg("caller_ty", caller_ty);
diag.arg("callee_ty", callee_ty);
}
AbiMismatchReturn { caller_ty, callee_ty } => {
diag.arg("caller_ty", caller_ty);
diag.arg("callee_ty", callee_ty);
}
}
}
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
Item = (&'x FnArg<'tcx, M::Provenance>, &'y ArgAbi<'tcx, Ty<'tcx>>),
>,
callee_abi: &ArgAbi<'tcx, Ty<'tcx>>,
callee_arg_idx: usize,
callee_arg: &mir::Place<'tcx>,
callee_ty: Ty<'tcx>,
already_live: bool,
Expand Down Expand Up @@ -298,6 +299,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Check compatibility
if !self.check_argument_compat(caller_abi, callee_abi)? {
throw_ub!(AbiMismatchArgument {
arg_idx: callee_arg_idx,
caller_ty: caller_abi.layout.ty,
callee_ty: callee_abi.layout.ty
});
Expand Down Expand Up @@ -424,7 +426,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// this is a single iterator (that handles `spread_arg`), then
// `pass_argument` would be the loop body. It takes care to
// not advance `caller_iter` for ignored arguments.
let mut callee_args_abis = callee_fn_abi.args.iter();
let mut callee_args_abis = callee_fn_abi.args.iter().enumerate();
for local in body.args_iter() {
// Construct the destination place for this argument. At this point all
// locals are still dead, so we cannot construct a `PlaceTy`.
Expand All @@ -445,21 +447,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
&[mir::ProjectionElem::Field(FieldIdx::from_usize(i), field_ty)],
*self.tcx,
);
let callee_abi = callee_args_abis.next().unwrap();
let (idx, callee_abi) = callee_args_abis.next().unwrap();
self.pass_argument(
&mut caller_args,
callee_abi,
idx,
&dest,
field_ty,
/* already_live */ true,
)?;
}
} else {
// Normal argument. Cannot mark it as live yet, it might be unsized!
let callee_abi = callee_args_abis.next().unwrap();
let (idx, callee_abi) = callee_args_abis.next().unwrap();
self.pass_argument(
&mut caller_args,
callee_abi,
idx,
&dest,
ty,
/* already_live */ false,
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,12 @@ pub enum UndefinedBehaviorInfo<'tcx> {
/// Trying to set discriminant to the niched variant, but the value does not match.
InvalidNichedEnumVariantWritten { enum_ty: Ty<'tcx> },
/// ABI-incompatible argument types.
AbiMismatchArgument { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
AbiMismatchArgument {
/// The index of the argument whose type is wrong.
arg_idx: usize,
caller_ty: Ty<'tcx>,
callee_ty: Ty<'tcx>,
},
/// ABI-incompatible return types.
AbiMismatchReturn { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ pub fn report_error<'tcx>(
helps.push(note_span!(span, "{:?} was deallocated here:", alloc_id));
}
}
AbiMismatchArgument { .. } | AbiMismatchReturn { .. } => {
AbiMismatchArgument { .. } => {
helps.push(note!("this means these two types are not *guaranteed* to be ABI-compatible across all targets"));
helps.push(note!("if you think this code should be accepted anyway, please report an issue with Miri"));
}
Expand Down
1 change: 1 addition & 0 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
.position(|b| !b)
{
throw_ub!(AbiMismatchArgument {
arg_idx: index,
caller_ty: caller_fn_abi.args[index].layout.ty,
callee_ty: callee_fn_abi.args[index].layout.ty
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ fn main() {
// These two types have the same size but are still not compatible.
let g = unsafe { std::mem::transmute::<fn(S), fn(A)>(f) };

g(Default::default()) //~ ERROR: calling a function with argument of type S passing data of type [i32; 4]
g(Default::default()) //~ ERROR: type S passing argument of type [i32; 4]
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type S passing data of type [i32; 4]
error: Undefined Behavior: calling a function whose parameter #1 has type S passing argument of type [i32; 4]
--> tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs:LL:CC
|
LL | g(Default::default())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ fn main() {

let g = unsafe { std::mem::transmute::<fn(f32), fn(i32)>(f) };

g(42) //~ ERROR: calling a function with argument of type f32 passing data of type i32
g(42) //~ ERROR: type f32 passing argument of type i32
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type f32 passing data of type i32
error: Undefined Behavior: calling a function whose parameter #1 has type f32 passing argument of type i32
--> tests/fail/function_pointers/abi_mismatch_int_vs_float.rs:LL:CC
|
LL | g(42)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ fn main() {

let g = unsafe { std::mem::transmute::<fn(*const [i32]), fn(*const i32)>(f) };

g(&42 as *const i32) //~ ERROR: calling a function with argument of type *const [i32] passing data of type *const i32
g(&42 as *const i32) //~ ERROR: type *const [i32] passing argument of type *const i32
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type *const [i32] passing data of type *const i32
error: Undefined Behavior: calling a function whose parameter #1 has type *const [i32] passing argument of type *const i32
--> tests/fail/function_pointers/abi_mismatch_raw_pointer.rs:LL:CC
|
LL | g(&42 as *const i32)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ fn main() {
let fnptr: fn(S2) = callee;
let fnptr: fn(S1) = unsafe { std::mem::transmute(fnptr) };
fnptr(S1(NonZero::new(1).unwrap()));
//~^ ERROR: calling a function with argument of type S2 passing data of type S1
//~^ ERROR: type S2 passing argument of type S1
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type S2 passing data of type S1
error: Undefined Behavior: calling a function whose parameter #1 has type S2 passing argument of type S1
--> tests/fail/function_pointers/abi_mismatch_repr_C.rs:LL:CC
|
LL | fnptr(S1(NonZero::new(1).unwrap()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ fn main() {

let g = unsafe { std::mem::transmute::<fn() -> u32, fn()>(f) };

g() //~ ERROR: calling a function with return type u32 passing return place of type ()
g() //~ ERROR: type u32 passing return place of type ()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ LL | g()
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
= help: if you think this code should be accepted anyway, please report an issue with Miri
= note: BACKTRACE:
= note: inside `main` at tests/fail/function_pointers/abi_mismatch_return_type.rs:LL:CC

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ fn main() {

let g = unsafe { std::mem::transmute::<fn((i32, i32)), fn(i32)>(f) };

g(42) //~ ERROR: calling a function with argument of type (i32, i32) passing data of type i32
g(42) //~ ERROR: type (i32, i32) passing argument of type i32
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type (i32, i32) passing data of type i32
error: Undefined Behavior: calling a function whose parameter #1 has type (i32, i32) passing argument of type i32
--> tests/fail/function_pointers/abi_mismatch_simple.rs:LL:CC
|
LL | g(42)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ fn main() {
// These two vector types have the same size but are still not compatible.
let g = unsafe { std::mem::transmute::<fn(simd::u32x8), fn(simd::u64x4)>(f) };

g(Default::default()) //~ ERROR: calling a function with argument of type std::simd::Simd<u32, 8> passing data of type std::simd::Simd<u64, 4>
g(Default::default()) //~ ERROR: type std::simd::Simd<u32, 8> passing argument of type std::simd::Simd<u64, 4>
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type std::simd::Simd<u32, 8> passing data of type std::simd::Simd<u64, 4>
error: Undefined Behavior: calling a function whose parameter #1 has type std::simd::Simd<u32, 8> passing argument of type std::simd::Simd<u64, 4>
--> tests/fail/function_pointers/abi_mismatch_vector.rs:LL:CC
|
LL | g(Default::default())
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/shims/input_arg_mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ fn main() {
} as u32;
let _ = unsafe {
close(fd);
//~^ ERROR: calling a function with argument of type i32 passing data of type u32
//~^ ERROR: type i32 passing argument of type u32
};
}
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32
error: Undefined Behavior: calling a function whose parameter #1 has type i32 passing argument of type u32
--> tests/fail/shims/input_arg_mismatch.rs:LL:CC
|
LL | close(fd);
Expand Down
2 changes: 0 additions & 2 deletions src/tools/miri/tests/fail/shims/return_type_mismatch.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ LL | close(fd);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
= help: if you think this code should be accepted anyway, please report an issue with Miri
= note: BACKTRACE:
= note: inside `main` at tests/fail/shims/return_type_mismatch.rs:LL:CC

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fn main() {
// the error should point to `become g(x)`,
// but tail calls mess up the backtrace it seems like...
f(0);
//~^ error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32
//~^ error: type i32 passing argument of type u32
}

fn f(x: u32) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32
error: Undefined Behavior: calling a function whose parameter #1 has type i32 passing argument of type u32
--> tests/fail/tail_calls/signature-mismatch-arg.rs:LL:CC
|
LL | f(0);
Expand Down
Loading