Skip to content
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

Miri ICE/possible miscompilation with diverging function returning repr(transparent) wrapper with uninhabited ZST, transmuted to function pointer returning wrapped field. #135802

Open
zachs18 opened this issue Jan 21, 2025 · 1 comment
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-miri Area: The miri tool C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@zachs18
Copy link
Contributor

zachs18 commented Jan 21, 2025

This code ICEs Miri, the normal compiler compiles this without complaint, but might be miscompiling it1, though a const version using -Zunleash-the-miri-inside-of-you does ICE the compiler.

Code

type Field = u8; // any non-1ZST probably
#[repr(transparent)]
struct Foo {
  _zst: std::convert::Infallible,
  _field: Field,
}
fn foo() -> Foo {
  panic!()
}
fn main() {
  let f: fn() -> Foo = foo;
  let f: fn() -> Field = unsafe { std::mem::transmute(f) };
  f();
}  
cargo +nightly miri run
modified version using `-Zunleash-the-miri-inside-of-you` that ICEs rustc
type Field = u8; // any non-1ZST probably
#[repr(transparent)]
struct Foo {
  _zst: std::convert::Infallible,
  _field: Field,
}
const fn foo() -> Foo {
    panic!()
}
fn main() {
    const {
        let f: fn() -> Foo = foo;
        let f: fn() -> Field = unsafe { std::mem::transmute(f) };
        f();
    }
}
RUSTFLAGS="-Zunleash-the-miri-inside-of-you" cargo +nightly run

Backtrace:

thread 'rustc' panicked at compiler/rustc_const_eval/src/interpret/call.rs:253:13:
assertion failed: caller_abi.eq_abi(callee_abi)
stack backtrace:
   0:     0x7e3cb9b652a5 - std::backtrace::Backtrace::create::h8985a2f6ef2eb84f
   1:     0x7e3cb80e39f5 - std::backtrace::Backtrace::force_capture::h9a611efb2a942dc9
   2:     0x7e3cb725a4e0 - std[4faddc71fb6fa0e5]::panicking::update_hook::<alloc[c55780341d73682]::boxed::Box<rustc_driver_impl[80a9ca323d3e3890]::install_ice_hook::{closure#1}>>::{closure#0}
   3:     0x7e3cb80fc333 - std::panicking::rust_panic_with_hook::hf47d9e178e038701
   4:     0x7e3cb80fbff6 - std::panicking::begin_panic_handler::{{closure}}::hd9b9f2d3dd54e86c
   5:     0x7e3cb80f99e9 - std::sys::backtrace::__rust_end_short_backtrace::h342bb668fc58e319
   6:     0x7e3cb80fbced - rust_begin_unwind
   7:     0x7e3cb4da8db0 - core::panicking::panic_fmt::hb3cd74fdfc019257
   8:     0x7e3cb5897b9c - core::panicking::panic::h92e08174b9fe42d1
   9:     0x7e3cb92c11bb - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<rustc_const_eval[e3d2a21e14ef9d90]::const_eval::machine::CompileTimeMachine>>::init_stack_frame
  10:     0x7e3cb92bde11 - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<rustc_const_eval[e3d2a21e14ef9d90]::const_eval::machine::CompileTimeMachine>>::init_fn_call
  11:     0x7e3cb6314e8f - rustc_const_eval[e3d2a21e14ef9d90]::const_eval::eval_queries::eval_to_allocation_raw_provider
  12:     0x7e3cb9041f5c - rustc_query_impl[283282ac12660651]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[283282ac12660651]::query_impl::eval_to_allocation_raw::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 24usize]>>
  13:     0x7e3cb9041fb7 - <rustc_query_impl[283282ac12660651]::query_impl::eval_to_allocation_raw::dynamic_query::{closure#2} as core[b8d8efd06dd057cd]::ops::function::FnOnce<(rustc_middle[d099a8b084c78b18]::ty::context::TyCtxt, rustc_middle[d099a8b084c78b18]::ty::PseudoCanonicalInput<rustc_middle[d099a8b084c78b18]::mir::interpret::GlobalId>)>>::call_once
  14:     0x7e3cb90406be - rustc_query_system[57efd1c10fae1b2]::query::plumbing::try_execute_query::<rustc_query_impl[283282ac12660651]::DynamicConfig<rustc_query_system[57efd1c10fae1b2]::query::caches::DefaultCache<rustc_middle[d099a8b084c78b18]::ty::PseudoCanonicalInput<rustc_middle[d099a8b084c78b18]::mir::interpret::GlobalId>, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 24usize]>>, false, false, false>, rustc_query_impl[283282ac12660651]::plumbing::QueryCtxt, true>
  15:     0x7e3cb903fffd - rustc_query_impl[283282ac12660651]::query_impl::eval_to_allocation_raw::get_query_incr::__rust_end_short_backtrace
  16:     0x7e3cb904475f - rustc_const_eval[e3d2a21e14ef9d90]::const_eval::eval_queries::eval_to_const_value_raw_provider
  17:     0x7e3cb9044554 - rustc_query_impl[283282ac12660651]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[283282ac12660651]::query_impl::eval_to_const_value_raw::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 24usize]>>
  18:     0x7e3cb904450d - <rustc_query_impl[283282ac12660651]::query_impl::eval_to_const_value_raw::dynamic_query::{closure#2} as core[b8d8efd06dd057cd]::ops::function::FnOnce<(rustc_middle[d099a8b084c78b18]::ty::context::TyCtxt, rustc_middle[d099a8b084c78b18]::ty::PseudoCanonicalInput<rustc_middle[d099a8b084c78b18]::mir::interpret::GlobalId>)>>::call_once
  19:     0x7e3cb903f2e6 - rustc_query_system[57efd1c10fae1b2]::query::plumbing::try_execute_query::<rustc_query_impl[283282ac12660651]::DynamicConfig<rustc_query_system[57efd1c10fae1b2]::query::caches::DefaultCache<rustc_middle[d099a8b084c78b18]::ty::PseudoCanonicalInput<rustc_middle[d099a8b084c78b18]::mir::interpret::GlobalId>, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 24usize]>>, false, true, false>, rustc_query_impl[283282ac12660651]::plumbing::QueryCtxt, true>
  20:     0x7e3cb903ebc7 - rustc_query_impl[283282ac12660651]::query_impl::eval_to_const_value_raw::get_query_incr::__rust_end_short_backtrace
  21:     0x7e3cb95e110b - <rustc_middle[d099a8b084c78b18]::ty::context::TyCtxt>::const_eval_resolve
  22:     0x7e3cb5825b39 - <rustc_mir_transform[e7af90bdb15a3f20]::known_panics_lint::ConstPropagator as rustc_middle[d099a8b084c78b18]::mir::visit::Visitor>::visit_operand
  23:     0x7e3cb5829080 - <rustc_mir_transform[e7af90bdb15a3f20]::known_panics_lint::ConstPropagator as rustc_middle[d099a8b084c78b18]::mir::visit::Visitor>::visit_assign
  24:     0x7e3cb582799b - <rustc_mir_transform[e7af90bdb15a3f20]::known_panics_lint::ConstPropagator as rustc_middle[d099a8b084c78b18]::mir::visit::Visitor>::visit_body
  25:     0x7e3cb95f79f9 - <rustc_mir_transform[e7af90bdb15a3f20]::known_panics_lint::KnownPanicsLint as rustc_mir_transform[e7af90bdb15a3f20]::pass_manager::MirLint>::run_lint
  26:     0x7e3cb880b6f3 - rustc_mir_transform[e7af90bdb15a3f20]::run_analysis_to_runtime_passes
  27:     0x7e3cb8c28174 - rustc_mir_transform[e7af90bdb15a3f20]::mir_drops_elaborated_and_const_checked
  28:     0x7e3cb8c27da5 - rustc_query_impl[283282ac12660651]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[283282ac12660651]::query_impl::mir_drops_elaborated_and_const_checked::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 8usize]>>
  29:     0x7e3cb8c2bcd9 - rustc_query_system[57efd1c10fae1b2]::query::plumbing::try_execute_query::<rustc_query_impl[283282ac12660651]::DynamicConfig<rustc_data_structures[ff6b6eb237e26604]::vec_cache::VecCache<rustc_span[6fdbe82b95f770dc]::def_id::LocalDefId, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 8usize]>, rustc_query_system[57efd1c10fae1b2]::dep_graph::graph::DepNodeIndex>, false, false, false>, rustc_query_impl[283282ac12660651]::plumbing::QueryCtxt, true>
  30:     0x7e3cb8c24dae - rustc_query_impl[283282ac12660651]::query_impl::mir_drops_elaborated_and_const_checked::get_query_incr::__rust_end_short_backtrace
  31:     0x7e3cb8c248f3 - <rustc_middle[d099a8b084c78b18]::hir::map::Map>::par_body_owners::<rustc_interface[5facaafd3cd44e6f]::passes::run_required_analyses::{closure#3}::{closure#0}>::{closure#0}
  32:     0x7e3cb8c21df4 - rustc_interface[5facaafd3cd44e6f]::passes::run_required_analyses
  33:     0x7e3cb976ca9e - rustc_interface[5facaafd3cd44e6f]::passes::analysis
  34:     0x7e3cb976ca6f - rustc_query_impl[283282ac12660651]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[283282ac12660651]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 0usize]>>
  35:     0x7e3cb97683cf - rustc_query_system[57efd1c10fae1b2]::query::plumbing::try_execute_query::<rustc_query_impl[283282ac12660651]::DynamicConfig<rustc_query_system[57efd1c10fae1b2]::query::caches::SingleCache<rustc_middle[d099a8b084c78b18]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[283282ac12660651]::plumbing::QueryCtxt, true>
  36:     0x7e3cb9767d47 - rustc_query_impl[283282ac12660651]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
  37:     0x7e3cb9820669 - rustc_interface[5facaafd3cd44e6f]::passes::create_and_enter_global_ctxt::<core[b8d8efd06dd057cd]::option::Option<rustc_interface[5facaafd3cd44e6f]::queries::Linker>, rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  38:     0x7e3cb9813896 - rustc_interface[5facaafd3cd44e6f]::interface::run_compiler::<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}
  39:     0x7e3cb9670807 - std[4faddc71fb6fa0e5]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_with_globals<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_pool_with_globals<rustc_interface[5facaafd3cd44e6f]::interface::run_compiler<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  40:     0x7e3cb96704d9 - <<std[4faddc71fb6fa0e5]::thread::Builder>::spawn_unchecked_<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_with_globals<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_pool_with_globals<rustc_interface[5facaafd3cd44e6f]::interface::run_compiler<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[b8d8efd06dd057cd]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  41:     0x7e3cb966fc6b - std::sys::pal::unix::thread::Thread::new::thread_start::h07063fc11dcd9adf
  42:     0x7e3cb389ca94 - start_thread
                               at ./nptl/pthread_create.c:447:8
  43:     0x7e3cb3929c3c - clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:78:0
  44:                0x0 - <unknown>


rustc version: 1.86.0-nightly (9a1d156f3 2025-01-19)
platform: x86_64-unknown-linux-gnu

query stack during panic:
#0 [eval_to_allocation_raw] const-evaluating + checking `main::{constant#0}`
#1 [eval_to_const_value_raw] simplifying constant for the type system `main::{constant#0}`
#2 [mir_drops_elaborated_and_const_checked] elaborating drops for `main`
#3 [analysis] running analysis passes on this crate
end of query stack

Meta

rustc --version --verbose:

rustc 1.86.0-nightly (9a1d156f3 2025-01-19)
binary: rustc
commit-hash: 9a1d156f38c51441ee51e5a068f1d0caf4bb0f27
commit-date: 2025-01-19
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7

Error output

Error output
thread 'rustc' panicked at /rustc/9a1d156f38c51441ee51e5a068f1d0caf4bb0f27/compiler/rustc_const_eval/src/interpret/call.rs:253:13:
assertion failed: caller_abi.eq_abi(callee_abi)
stack backtrace:
   0:     0x78aed8af951a - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h70d5098cfd90b01a
   1:     0x78aed9212da6 - core::fmt::write::h854c563aac02d08a
   2:     0x78aeda171291 - std::io::Write::write_fmt::hac4174e389a0e8e6
   3:     0x78aed8af9372 - std::sys::backtrace::BacktraceLock::print::hc6aba0d6b3a91e1f
   4:     0x78aed8afb7f2 - std::panicking::default_hook::{{closure}}::h9628a97795328020
   5:     0x78aed8afb67a - std::panicking::default_hook::h0dc7e102448ae736
   6:     0x78aed7c59eeb - std[4faddc71fb6fa0e5]::panicking::update_hook::<alloc[c55780341d73682]::boxed::Box<rustc_driver_impl[80a9ca323d3e3890]::install_ice_hook::{closure#1}>>::{closure#0}
   7:     0x78aed8afc333 - std::panicking::rust_panic_with_hook::hf47d9e178e038701
   8:     0x78aed8afbff6 - std::panicking::begin_panic_handler::{{closure}}::hd9b9f2d3dd54e86c
   9:     0x78aed8af99e9 - std::sys::backtrace::__rust_end_short_backtrace::h342bb668fc58e319
  10:     0x78aed8afbced - rust_begin_unwind
  11:     0x78aed57a8db0 - core::panicking::panic_fmt::hb3cd74fdfc019257
  12:     0x78aed6297b9c - core::panicking::panic::h92e08174b9fe42d1
  13:     0x592a4689f7ae - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<miri[d18ac4a41561b88d]::machine::MiriMachine>>::check_argument_compat
  14:     0x592a4689ec5a - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<miri[d18ac4a41561b88d]::machine::MiriMachine>>::init_stack_frame
  15:     0x592a4689c98b - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<miri[d18ac4a41561b88d]::machine::MiriMachine>>::init_fn_call
  16:     0x592a46915db4 - miri[d18ac4a41561b88d]::eval::eval_entry::{closure#0}
  17:     0x592a46911e9b - miri[d18ac4a41561b88d]::eval::eval_entry
  18:     0x592a467c4226 - <miri[e9b5d2e94aebaf6c]::MiriCompilerCalls as rustc_driver_impl[80a9ca323d3e3890]::Callbacks>::after_analysis
  19:     0x78aeda220676 - rustc_interface[5facaafd3cd44e6f]::passes::create_and_enter_global_ctxt::<core[b8d8efd06dd057cd]::option::Option<rustc_interface[5facaafd3cd44e6f]::queries::Linker>, rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  20:     0x78aeda213896 - rustc_interface[5facaafd3cd44e6f]::interface::run_compiler::<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}
  21:     0x78aeda070807 - std[4faddc71fb6fa0e5]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_with_globals<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_pool_with_globals<rustc_interface[5facaafd3cd44e6f]::interface::run_compiler<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  22:     0x78aeda0704d9 - <<std[4faddc71fb6fa0e5]::thread::Builder>::spawn_unchecked_<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_with_globals<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_pool_with_globals<rustc_interface[5facaafd3cd44e6f]::interface::run_compiler<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[b8d8efd06dd057cd]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  23:     0x78aeda06fc6b - std::sys::pal::unix::thread::Thread::new::thread_start::h07063fc11dcd9adf
  24:     0x78aed429ca94 - start_thread
                               at ./nptl/pthread_create.c:447:8
  25:     0x78aed4329c3c - clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:78:0
  26:                0x0 - <unknown>

error: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/miri/issues/new

note: please make sure that you have updated to the latest nightly

note: please attach the file at `/tmp/sadkjlhfsakdf/rustc-ice-2025-01-21T00_17_45-3693735.txt` to your bug report

note: compiler flags: --crate-type bin -C embed-bitcode=no -C debuginfo=2 -C incremental=[REDACTED]

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack

Miri caused an ICE during evaluation. Here's the interpreter backtrace at the time of the panic:
note: the place in the program where the ICE was triggered
  --> src/main.rs:7:5
   |
7  |     panic!()
   |     ^^^^^^^^
   |
   = note: BACKTRACE:
   = note: inside `foo` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic.rs:90:9: 90:30
note: inside `main`
  --> src/main.rs:12:5
   |
12 |     f();
   |     ^^^
   = note: inside `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5: 250:71
   = note: inside `std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/backtrace.rs:152:18: 152:21
   = note: inside closure at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:194:18: 194:75
   = note: inside `std::ops::function::impls::<impl std::ops::FnOnce<()> for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:284:13: 284:31
   = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:587:40: 587:43
   = note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:550:19: 550:88
   = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33
   = note: inside closure at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:163:24: 163:49
   = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:587:40: 587:43
   = note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#0}}>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:550:19: 550:88
   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:358:14: 358:33
   = note: inside `std::rt::lang_start_internal` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:159:5: 181:7
   = note: inside `std::rt::lang_start::<()>` at /home/zachary/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:193:5: 198:6
   = note: this note originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

ICE file

thread 'rustc' panicked at /rustc/9a1d156f38c51441ee51e5a068f1d0caf4bb0f27/compiler/rustc_const_eval/src/interpret/call.rs:253:13:
assertion failed: caller_abi.eq_abi(callee_abi)
stack backtrace:
   0:     0x78aeda5652a5 - std::backtrace::Backtrace::create::h8985a2f6ef2eb84f
   1:     0x78aed8ae39f5 - std::backtrace::Backtrace::force_capture::h9a611efb2a942dc9
   2:     0x78aed7c5a4e0 - std[4faddc71fb6fa0e5]::panicking::update_hook::<alloc[c55780341d73682]::boxed::Box<rustc_driver_impl[80a9ca323d3e3890]::install_ice_hook::{closure#1}>>::{closure#0}
   3:     0x78aed8afc333 - std::panicking::rust_panic_with_hook::hf47d9e178e038701
   4:     0x78aed8afbff6 - std::panicking::begin_panic_handler::{{closure}}::hd9b9f2d3dd54e86c
   5:     0x78aed8af99e9 - std::sys::backtrace::__rust_end_short_backtrace::h342bb668fc58e319
   6:     0x78aed8afbced - rust_begin_unwind
   7:     0x78aed57a8db0 - core::panicking::panic_fmt::hb3cd74fdfc019257
   8:     0x78aed6297b9c - core::panicking::panic::h92e08174b9fe42d1
   9:     0x592a4689f7ae - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<miri[d18ac4a41561b88d]::machine::MiriMachine>>::check_argument_compat
  10:     0x592a4689ec5a - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<miri[d18ac4a41561b88d]::machine::MiriMachine>>::init_stack_frame
  11:     0x592a4689c98b - <rustc_const_eval[e3d2a21e14ef9d90]::interpret::eval_context::InterpCx<miri[d18ac4a41561b88d]::machine::MiriMachine>>::init_fn_call
  12:     0x592a46915db4 - miri[d18ac4a41561b88d]::eval::eval_entry::{closure#0}
  13:     0x592a46911e9b - miri[d18ac4a41561b88d]::eval::eval_entry
  14:     0x592a467c4226 - <miri[e9b5d2e94aebaf6c]::MiriCompilerCalls as rustc_driver_impl[80a9ca323d3e3890]::Callbacks>::after_analysis
  15:     0x78aeda220676 - rustc_interface[5facaafd3cd44e6f]::passes::create_and_enter_global_ctxt::<core[b8d8efd06dd057cd]::option::Option<rustc_interface[5facaafd3cd44e6f]::queries::Linker>, rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  16:     0x78aeda213896 - rustc_interface[5facaafd3cd44e6f]::interface::run_compiler::<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}
  17:     0x78aeda070807 - std[4faddc71fb6fa0e5]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_with_globals<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_pool_with_globals<rustc_interface[5facaafd3cd44e6f]::interface::run_compiler<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  18:     0x78aeda0704d9 - <<std[4faddc71fb6fa0e5]::thread::Builder>::spawn_unchecked_<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_with_globals<rustc_interface[5facaafd3cd44e6f]::util::run_in_thread_pool_with_globals<rustc_interface[5facaafd3cd44e6f]::interface::run_compiler<(), rustc_driver_impl[80a9ca323d3e3890]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[b8d8efd06dd057cd]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  19:     0x78aeda06fc6b - std::sys::pal::unix::thread::Thread::new::thread_start::h07063fc11dcd9adf
  20:     0x78aed429ca94 - start_thread
                               at ./nptl/pthread_create.c:447:8
  21:     0x78aed4329c3c - clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:78:0
  22:                0x0 - <unknown>


rustc version: 1.86.0-nightly (9a1d156f3 2025-01-19)
platform: x86_64-unknown-linux-gnu

query stack during panic:
end of query stack

@rustbot label +A-miri +A-ABI


This shouldn't ICE regardless, but whether there is a miscompilation depends on if the original code is sound:

CC rust-lang/unsafe-code-guidelines#485

Possible Miscompilation

Does #[repr(transparent)]s ABI-compatility guarantee apply in the prescence of uninhabited 1-ZST fields?

A #[repr(transparent)] wrapper that contains an uninhabited 1-ZST field gets Uninhabited ABI IIUC, which may contradict the guarantees about #[repr(transparent)] wrappers being ABI-compatible.

Consider Foo from above:

type Field = u8; // any non-1ZST probably
#[repr(transparent)]
struct Foo {
  _zst: std::convert::Infallible,
  _field: Field,
}

If #[repr(transparent)]'s ABI-compatility guarantees do apply, then the above code should be sound:

  1. If a function returns Foo, it must diverge (e.g. by panicking).
  2. If Foo is ABI-compatible with Field, then it should be sound to transmute a function pointer to a diverging fn() -> Foo into a fn() -> Field that also diverges.
rustc_layout(debug)

Using #![feature(rustc_attrs)] and #[rustc_layout(debug)] we see that the ABI it has is

error: layout_of(Foo) = Layout {
          // snip
           abi: Uninhabited,
          // snip
       }

whereas Field has

error: layout_of(u8) = Layout {
           // snip
           abi: Scalar(
               Initialized {
                   value: Int(
                       I8,
                       false,
                   ),
                   valid_range: 0..=255,
               },
           ),
           // snip
        }

Possible Miscompilation

Assuming this is supposed to be sound, then there is an observable miscompilation here too. Where Field is returned by invisible reference, fn(u32) -> Foo does not return Foo by invisible reference, so transmuting fn(u32) -> Foo into fn(u32) -> Field will pass a different number of arguments.

Specifically on x86_64-unknown-linux-gnu: If Field is returned on the stack, then fn(..) -> Foo does not reserve stack space or pass a hidden reference parameter, but fn(..) -> Field does. This can be made into an observable miscompilation if the function takes parameters: (playground link, IIUC: the invisible reference is being passed, but the callee isn't expecting it, so it thinks it's the first "real" parameter instead (caller: ret by-ref in rdi, x in rsi; callee: ret uninhabited, x in rdi)).

Footnotes

  1. see "Possible Miscompilation" section

@zachs18 zachs18 added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 21, 2025
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. A-ABI Area: Concerning the application binary interface (ABI) A-miri Area: The miri tool labels Jan 21, 2025
@ia0
Copy link
Contributor

ia0 commented Jan 21, 2025

I would argue the original code is unsound. The intent (coming from the name) of repr(transparent) is to have the same runtime behavior as the "wrapped" field. Using an uninhabited 1-ZST breaks this intent. I believe this is an oversight of layout.repr.transparent.constraint-field. In particular, I would expect the first bullet point to be (added term in bold):

  • any number of inhabited fields with size 0 and alignment 1 (e.g. PhantomData<T>), and

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-miri Area: The miri tool C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants