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: InvalidProgram(ConstPropNonsense): uninhabited variant in project_downcast #115145

Closed
saethlin opened this issue Aug 23, 2023 · 25 comments
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-coroutines Area: Coroutines A-layout Area: Memory layout of types C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-high High priority S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@saethlin
Copy link
Member

saethlin commented Aug 23, 2023

Reduced example: #115145 (comment)

https://github.com/axodotdev/axoasset at 10e2f44ee1bccaa5ae0dca28ee5061af04c0ae8d

MIRIFLAGS=-Zmiri-disable-isolation cargo miri test it_copies_remote_assets

Error output

error: internal compiler error: src/tools/miri/src/diagnostics.rs:294:17: This error should be impossible in Miri: InvalidProgram(ConstPropNonsense)
Backtrace

test it_copies_remote_assets ... error: internal compiler error: src/tools/miri/src/diagnostics.rs:294:17: This error should be impossible in Miri: InvalidProgram(ConstPropNonsense)

thread 'rustc' panicked at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/compiler/rustc_errors/src/lib.rs:1635:9:
Box<dyn Any>
stack backtrace:
   0:     0x7f8f3a0ee0fc - std::backtrace_rs::backtrace::libunwind::trace::h9e6789d755ef2e35
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x7f8f3a0ee0fc - std::backtrace_rs::backtrace::trace_unsynchronized::hb3533227af2eed61
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x7f8f3a0ee0fc - std::sys_common::backtrace::_print_fmt::hc7dbc1325a62fad4
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x7f8f3a0ee0fc - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::he15329baacfb890f
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x7f8f3a1543bc - core::fmt::rt::Argument::fmt::he237d6d4e685b998
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/core/src/fmt/rt.rs:138:9
   5:     0x7f8f3a1543bc - core::fmt::write::h70fc50f283d0f28f
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/core/src/fmt/mod.rs:1094:21
   6:     0x7f8f3a0e0c1e - std::io::Write::write_fmt::hddcd4db09551f1e4
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/io/mod.rs:1714:15
   7:     0x7f8f3a0edee4 - std::sys_common::backtrace::_print::h79b5981c192eb87e
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x7f8f3a0edee4 - std::sys_common::backtrace::print::h4e1fc678281db5ea
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x7f8f3a0f0fda - std::panicking::panic_hook_with_disk_dump::{{closure}}::h2f6637765d241d6e
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/panicking.rs:278:22
  10:     0x7f8f3a0f0cc7 - std::panicking::panic_hook_with_disk_dump::hdf84cf3f221731ff
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/panicking.rs:312:9
  11:     0x7f8f38f0e0b9 - <rustc_driver_impl[f90d201525556a1f]::install_ice_hook::{closure#0} as core[e05ed4681f3f1168]::ops::function::FnOnce<(&core[e05ed4681f3f1168]::panic::panic_info::PanicInfo,)>>::call_once::{shim:vtable#0}
  12:     0x7f8f3a0f1880 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h18e5faf377bd4349
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/alloc/src/boxed.rs:2021:9
  13:     0x7f8f3a0f1880 - std::panicking::rust_panic_with_hook::hdde37fc27effc37e
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/panicking.rs:733:13
  14:     0x7f8f394367d1 - std[5f485339d878b58d]::panicking::begin_panic::<rustc_errors[aa284a60f2852f9]::ExplicitBug>::{closure#0}
  15:     0x7f8f39434a96 - std[5f485339d878b58d]::sys_common::backtrace::__rust_end_short_backtrace::<std[5f485339d878b58d]::panicking::begin_panic<rustc_errors[aa284a60f2852f9]::ExplicitBug>::{closure#0}, !>
  16:     0x7f8f393edfa6 - std[5f485339d878b58d]::panicking::begin_panic::<rustc_errors[aa284a60f2852f9]::ExplicitBug>
  17:     0x7f8f39487d24 - <rustc_errors[aa284a60f2852f9]::HandlerInner>::bug::<alloc[1fa734c4d2bb695]::string::String>
  18:     0x7f8f39487bb6 - <rustc_errors[aa284a60f2852f9]::Handler>::bug::<alloc[1fa734c4d2bb695]::string::String>
  19:     0x7f8f3946d55c - rustc_middle[767f7e5b95c87cd]::util::bug::opt_span_bug_fmt::<rustc_span[9b5bef724011fe8f]::span_encoding::Span>::{closure#0}
  20:     0x7f8f3946bc0a - rustc_middle[767f7e5b95c87cd]::ty::context::tls::with_opt::<rustc_middle[767f7e5b95c87cd]::util::bug::opt_span_bug_fmt<rustc_span[9b5bef724011fe8f]::span_encoding::Span>::{closure#0}, !>::{closure#0}
  21:     0x7f8f3946bbd8 - rustc_middle[767f7e5b95c87cd]::ty::context::tls::with_context_opt::<rustc_middle[767f7e5b95c87cd]::ty::context::tls::with_opt<rustc_middle[767f7e5b95c87cd]::util::bug::opt_span_bug_fmt<rustc_span[9b5bef724011fe8f]::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
  22:     0x7f8f376b7ae0 - rustc_middle[767f7e5b95c87cd]::util::bug::bug_fmt
  23:     0x55fa0204ed3a - miri[f8f5eaf6d04f8c74]::diagnostics::report_error
  24:     0x55fa02053f32 - miri[f8f5eaf6d04f8c74]::eval::eval_entry
  25:     0x55fa01fa99f7 - <rustc_middle[767f7e5b95c87cd]::ty::context::GlobalCtxt>::enter::<<miri[51939fbf34570118]::MiriCompilerCalls as rustc_driver_impl[f90d201525556a1f]::Callbacks>::after_analysis::{closure#0}, ()>
  26:     0x55fa01fa1914 - <miri[51939fbf34570118]::MiriCompilerCalls as rustc_driver_impl[f90d201525556a1f]::Callbacks>::after_analysis
  27:     0x7f8f381d5c0a - <rustc_interface[27d2f6b8fe428ec0]::interface::Compiler>::enter::<rustc_driver_impl[f90d201525556a1f]::run_compiler::{closure#1}::{closure#2}, core[e05ed4681f3f1168]::result::Result<core[e05ed4681f3f1168]::option::Option<rustc_interface[27d2f6b8fe428ec0]::queries::Linker>, rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>>
  28:     0x7f8f381d2f18 - std[5f485339d878b58d]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[27d2f6b8fe428ec0]::util::run_in_thread_pool_with_globals<rustc_interface[27d2f6b8fe428ec0]::interface::run_compiler<core[e05ed4681f3f1168]::result::Result<(), rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>, rustc_driver_impl[f90d201525556a1f]::run_compiler::{closure#1}>::{closure#0}, core[e05ed4681f3f1168]::result::Result<(), rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[e05ed4681f3f1168]::result::Result<(), rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>>
  29:     0x7f8f381d26a5 - <<std[5f485339d878b58d]::thread::Builder>::spawn_unchecked_<rustc_interface[27d2f6b8fe428ec0]::util::run_in_thread_pool_with_globals<rustc_interface[27d2f6b8fe428ec0]::interface::run_compiler<core[e05ed4681f3f1168]::result::Result<(), rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>, rustc_driver_impl[f90d201525556a1f]::run_compiler::{closure#1}>::{closure#0}, core[e05ed4681f3f1168]::result::Result<(), rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[e05ed4681f3f1168]::result::Result<(), rustc_span[9b5bef724011fe8f]::ErrorGuaranteed>>::{closure#1} as core[e05ed4681f3f1168]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  30:     0x7f8f3a0fc1e5 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h6086e9a313a3964c
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/alloc/src/boxed.rs:2007:9
  31:     0x7f8f3a0fc1e5 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h930455f80652281f
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/alloc/src/boxed.rs:2007:9
  32:     0x7f8f3a0fc1e5 - std::sys::unix::thread::Thread::new::thread_start::hbdbfdb70d010bf36
                               at /rustc/ef85656a10657ba5e4f7fe2931a4ca6293138d51/library/std/src/sys/unix/thread.rs:108:17
  33:     0x7f8f35a8c9eb - <unknown>
  34:     0x7f8f35b10dfc - <unknown>
  35:                0x0 - <unknown>

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

note: please attach the file at `/tmp/axoasset/rustc-ice-2023-08-23T18:31:20.771630796Z-2899178.txt` to your bug report

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental=[REDACTED] -Z miri-disable-isolation

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

query stack during panic:
end of query stack
error: aborting due to previous error

error: test failed, to rerun pass `--test remote_copy`

searched nightlies: from nightly-2023-01-01 to nightly-2023-08-14
regressed nightly: nightly-2023-07-26
searched commit range: 31395ec...864bdf7
regressed commit: 4fc6b33

bisected with cargo-bisect-rustc v0.6.6

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start 2023-01-01 --end 2023-08-14 --script script -c miri --with-src 
@saethlin saethlin added 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. C-bug Category: This is a bug. A-const-eval Area: constant evaluation (mir interpretation) labels Aug 23, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 23, 2023
@compiler-errors compiler-errors added E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 23, 2023
@RalfJung
Copy link
Member

Can you run this with MIRI_BACKTRACE=1 so we learn where in the code the error is triggered?

Also, Miri should print an interpreter backtrace of where in the crate it was when the error happened; please show that as well.

@saethlin
Copy link
Member Author

I set that environment variable and I do not get any additional output. There is also no interpreter backtrace.

@RalfJung
Copy link
Member

RalfJung commented Aug 27, 2023 via email

@saethlin
Copy link
Member Author

Both of those flags print the same backtrace before the ICE:

An error occurred in the MIR interpreter:
   0: <rustc_middle::mir::interpret::error::InterpErrorInfo as core::convert::From<rustc_middle::mir::interpret::error::InterpError>>::from
   1: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::MiriMachine>>::project_downcast::<rustc_const_eval::interpret::place::PlaceTy<miri::machine::Provenance>>
   2: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::MiriMachine>>::eval_place
   3: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::MiriMachine>>::eval_rvalue_into_place
   4: <rustc_const_eval::interpret::eval_context::InterpCx<miri::machine::MiriMachine> as miri::concurrency::thread::EvalContextExt>::run_threads
   5: miri::eval::eval_entry
   6: <rustc_middle::ty::context::GlobalCtxt>::enter::<<miri::MiriCompilerCalls as rustc_driver_impl::Callbacks>::after_analysis::{closure#0}, ()>
   7: <miri::MiriCompilerCalls as rustc_driver_impl::Callbacks>::after_analysis
   8: <rustc_interface::interface::Compiler>::enter::<rustc_driver_impl::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
   9: std::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
  10: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  11: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/69e97df5ce571a777acd654ec3697ae8d25962ea/library/alloc/src/boxed.rs:2007:9
  12: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/69e97df5ce571a777acd654ec3697ae8d25962ea/library/alloc/src/boxed.rs:2007:9
  13: std::sys::unix::thread::Thread::new::thread_start
             at /rustc/69e97df5ce571a777acd654ec3697ae8d25962ea/library/std/src/sys/unix/thread.rs:108:17
  14: <unknown>
  15: <unknown>

@RalfJung
Copy link
Member

Oh interesting, it seems to be triggering this:

if layout.abi.is_uninhabited() {
// `read_discriminant` should have excluded uninhabited variants... but ConstProp calls
// us on dead code.
throw_inval!(ConstPropNonsense)
}

So there's something funny going on with an enum. Hopefully #115272 will let us capture an interpreter backtrace.

@saethlin
Copy link
Member Author

Yep, that PR seems to work:

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
   --> /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/deadpool-0.9.5/src/managed/mod.rs:663:5
    |
663 |     timeout_type: TimeoutType,
    |     ^^^^^^^^^^^^
    |
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/deadpool-0.9.5/src/managed/mod.rs:663:5: 663:17
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/deadpool-0.9.5/src/managed/mod.rs:384:14: 384:19
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/deadpool-0.9.5/src/managed/mod.rs:327:44: 327:49
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wiremock-0.5.19/src/mock_server/pool.rs:43:10: 43:15
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wiremock-0.5.19/src/mock_server/exposed_server.rs:112:59: 112:64
note: inside closure
   --> tests/remote_copy.rs:11:43
    |
11  |     let mock_server = MockServer::start().await;
    |                                           ^^^^^
    = note: inside `<std::pin::Pin<&mut dyn std::future::Future<Output = ()>> as std::future::Future>::poll` at /home/ben/rust/library/core/src/future/future.rs:125:9: 125:61
    = note: inside `<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>> as std::future::Future>::poll` at /home/ben/rust/library/core/src/future/future.rs:125:9: 125:61
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:665:57: 665:86
    = note: inside `tokio::runtime::coop::with_budget::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}]>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/coop.rs:107:5: 107:8
    = note: inside `tokio::runtime::coop::budget::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}]>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/coop.rs:73:5: 73:38
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:665:25: 665:87
    = note: inside `tokio::runtime::scheduler::current_thread::Context::enter::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}]>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:410:19: 410:22
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:664:36: 666:23
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:743:68: 743:84
    = note: inside `tokio::runtime::context::scoped::Scoped::<tokio::runtime::scheduler::Context>::set::<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::enter<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>::{closure#0}], (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context/scoped.rs:40:9: 40:12
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context.rs:176:26: 176:47
    = note: inside `std::thread::LocalKey::<tokio::runtime::context::Context>::try_with::<[closure@tokio::runtime::context::set_scheduler<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::enter<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>::{closure#0}]>::{closure#0}], (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/ben/rust/library/std/src/thread/local.rs:270:16: 270:31
    = note: inside `std::thread::LocalKey::<tokio::runtime::context::Context>::with::<[closure@tokio::runtime::context::set_scheduler<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::enter<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>::{closure#0}]>::{closure#0}], (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/ben/rust/library/std/src/thread/local.rs:246:9: 246:25
    = note: inside `tokio::runtime::context::set_scheduler::<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::enter<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>::{closure#0}]>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context.rs:176:9: 176:48
    = note: inside `tokio::runtime::scheduler::current_thread::CoreGuard::<'_>::enter::<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:743:27: 743:85
    = note: inside `tokio::runtime::scheduler::current_thread::CoreGuard::<'_>::block_on::<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:652:19: 720:11
    = note: inside closure at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:175:28: 175:49
    = note: inside `tokio::runtime::context::runtime::enter_runtime::<[closure@tokio::runtime::scheduler::current_thread::CurrentThread::block_on<std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>::{closure#0}], ()>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context/runtime.rs:65:16: 65:38
    = note: inside `tokio::runtime::scheduler::current_thread::CurrentThread::block_on::<std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/current_thread/mod.rs:167:9: 198:11
    = note: inside `tokio::runtime::Runtime::block_on::<std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>` at /home/ben/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/runtime.rs:347:47: 347:88
note: inside `it_copies_remote_assets`
   --> tests/remote_copy.rs:20:5
    |
20  | /     for route in routes {
21  | |         let resp_string = if route.to_uppercase().contains("README") {
22  | |             &readme_string
23  | |         } else {
...   |
38  | |         assert!(copied_file.exists());
39  | |     }
    | |_____^
note: inside closure
   --> tests/remote_copy.rs:10:36
    |
9   | #[tokio::test]
    | -------------- in this procedural macro expansion
10  | async fn it_copies_remote_assets() {
    |                                    ^
    = note: inside `<[closure@tests/remote_copy.rs:10:7: 40:2] as std::ops::FnOnce<()>>::call_once - shim` at /home/ben/rust/library/core/src/ops/function.rs:250:5: 250:71
    = note: inside `<fn() -> std::result::Result<(), std::string::String> as std::ops::FnOnce<()>>::call_once - shim(fn() -> std::result::Result<(), std::string::String>)` at /home/ben/rust/library/core/src/ops/function.rs:250:5: 250:71
    = note: inside `test::__rust_begin_short_backtrace::<std::result::Result<(), std::string::String>, fn() -> std::result::Result<(), std::string::String>>` at /home/ben/rust/library/test/src/lib.rs:626:18: 626:21
    = note: inside `test::types::RunnableTest::run` at /home/ben/rust/library/test/src/types.rs:146:40: 146:71
    = note: inside closure at /home/ben/rust/library/test/src/lib.rs:649:60: 649:79
    = note: inside `<std::panic::AssertUnwindSafe<[closure@test::run_test_in_process::{closure#0}]> as std::ops::FnOnce<()>>::call_once` at /home/ben/rust/library/core/src/panic/unwind_safe.rs:271:9: 271:19
    = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<[closure@test::run_test_in_process::{closure#0}]>, std::result::Result<(), std::string::String>>` at /home/ben/rust/library/std/src/panicking.rs:524:40: 524:43
    = note: inside `std::panicking::r#try::<std::result::Result<(), std::string::String>, std::panic::AssertUnwindSafe<[closure@test::run_test_in_process::{closure#0}]>>` at /home/ben/rust/library/std/src/panicking.rs:488:19: 488:81
    = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<[closure@test::run_test_in_process::{closure#0}]>, std::result::Result<(), std::string::String>>` at /home/ben/rust/library/std/src/panic.rs:142:14: 142:33
    = note: inside `test::run_test_in_process` at /home/ben/rust/library/test/src/lib.rs:649:27: 649:81
    = note: inside closure at /home/ben/rust/library/test/src/lib.rs:572:43: 580:18
    = note: inside closure at /home/ben/rust/library/test/src/lib.rs:600:41: 600:83
    = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::<[closure@test::run_test::{closure#1}], ()>` at /home/ben/rust/library/std/src/sys_common/backtrace.rs:154:18: 154:21
    = note: inside closure at /home/ben/rust/library/std/src/thread/mod.rs:529:17: 529:78
    = note: inside `<std::panic::AssertUnwindSafe<[closure@std::thread::Builder::spawn_unchecked_<'_, '_, [closure@test::run_test::{closure#1}], ()>::{closure#1}::{closure#0}]> as std::ops::FnOnce<()>>::call_once` at /home/ben/rust/library/core/src/panic/unwind_safe.rs:271:9: 271:19
    = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<[closure@std::thread::Builder::spawn_unchecked_<'_, '_, [closure@test::run_test::{closure#1}], ()>::{closure#1}::{closure#0}]>, ()>` at /home/ben/rust/library/std/src/panicking.rs:524:40: 524:43
    = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<[closure@std::thread::Builder::spawn_unchecked_<'_, '_, [closure@test::run_test::{closure#1}], ()>::{closure#1}::{closure#0}]>>` at /home/ben/rust/library/std/src/panicking.rs:488:19: 488:81
    = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<[closure@std::thread::Builder::spawn_unchecked_<'_, '_, [closure@test::run_test::{closure#1}], ()>::{closure#1}::{closure#0}]>, ()>` at /home/ben/rust/library/std/src/panic.rs:142:14: 142:33
    = note: inside closure at /home/ben/rust/library/std/src/thread/mod.rs:528:30: 530:16
    = note: inside `<[closure@std::thread::Builder::spawn_unchecked_<'_, '_, [closure@test::run_test::{closure#1}], ()>::{closure#1}] as std::ops::FnOnce<()>>::call_once - shim(vtable)` at /home/ben/rust/library/core/src/ops/function.rs:250:5: 250:71
    = note: inside `<std::boxed::Box<dyn std::ops::FnOnce()> as std::ops::FnOnce<()>>::call_once` at /home/ben/rust/library/alloc/src/boxed.rs:2007:9: 2007:52
    = note: inside `<std::boxed::Box<std::boxed::Box<dyn std::ops::FnOnce()>> as std::ops::FnOnce<()>>::call_once` at /home/ben/rust/library/alloc/src/boxed.rs:2007:9: 2007:52
    = note: inside `std::sys::unix::thread::Thread::new::thread_start` at /home/ben/rust/library/std/src/sys/unix/thread.rs:108:17: 108:64
    = note: this note originates in the attribute macro `::core::prelude::v1::test` which comes from the expansion of the attribute macro `tokio::test` (in Nightly builds, run with -Z macro-backtrace for more info)

@RalfJung
Copy link
Member

Oh, this may be a downcast on a generator. I had not considered those. Hm...

I think currently we guarantee that even uninhabited variants have sufficient space allocated to them, so maybe we can just remove that check? Still would be nice to have a small example.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Aug 30, 2023
miri/diagnostics: don't forget to print_backtrace when ICEing on unexpected errors

This should fix the missing output encountered [here](rust-lang#115145 (comment)).

r? `@saethlin`
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Aug 31, 2023
miri/diagnostics: don't forget to print_backtrace when ICEing on unexpected errors

This should fix the missing output encountered [here](rust-lang/rust#115145 (comment)).

r? `@saethlin`
@saethlin saethlin self-assigned this Dec 10, 2023
@saethlin
Copy link
Member Author

I've minimized deadpool down to this so far, stuck on removing the use of deadpool_runtime:

use deadpool_runtime::Runtime;
use futures_lite::future::block_on;
use std::time::Duration;

enum TimeoutType {
    Create,
}

async fn apply_timeout(
    timeout_type: TimeoutType,
) -> Result<(), TimeoutType> {
    match None::<Runtime> {
        None => {
            let _ = create().await;
            Ok(())
        }
        Some(r) => {
            let _ = r.timeout(Duration::from_secs(1), create()).await;
            Err(timeout_type)
        }
    }
}

async fn create() -> Result<(), TimeoutType> {
    Ok(())
}

fn main() {
    let _ = block_on(apply_timeout(TimeoutType::Create));
}

@RalfJung RalfJung changed the title Miri ICE: InvalidProgram(ConstPropNonsense) Miri ICE: InvalidProgram(ConstPropNonsense): uninhabited variant in project_downcast Dec 10, 2023
@saethlin
Copy link
Member Author

Further reduced by @zachs18 to something we can put in a test case:

#![feature(noop_waker)]
use std::future::Future;

enum Runtime {}

async fn run(_: Runtime) {}

async fn apply_timeout() {
    let c = async {};
    match None::<Runtime> {
        None => {
            c.await;
        },
        Some(r) => {
            run(r).await;
        }
    }
}

fn main() {
    let waker = std::task::Waker::noop();
    let mut ctx = std::task::Context::from_waker(&waker);
    let fut = std::pin::pin!(apply_timeout());
    let _ = fut.poll(&mut ctx);
}

@saethlin saethlin added S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue and removed E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example labels Dec 10, 2023
@RalfJung
Copy link
Member

I can't say I understand why we are projecting to an uninhabited variant here... but I guess the point is, the lowering is picking any variant that has the field we need, and there's no logic that would avoid using an uninhabited variant for that?

@saethlin
Copy link
Member Author

I don't understand either, and I think at this point it would be good for me to understand exactly what about the generator lowering is problematic here. I've mostly ignored the MIR because there's quite a lot.

@saethlin
Copy link
Member Author

saethlin commented Dec 11, 2023

and there's no logic that would avoid using an uninhabited variant for that?

I started looking into this question but then realized that since all our lowering code is working on polymorphic MIR I'm not certain this situation is even possible to avoid in lowering.

@RalfJung
Copy link
Member

RalfJung commented Dec 12, 2023

Hm... I would think that there's always a "current" state in generator lowering and one can use that to access the field, and we know that the current state has all fields inhabited because otherwise it couldn't even become the current state.

But I'm not sure how the lowering actually works so this is probably naive. Also, even for enums, we might want to lower code like this

enum Option2 {
  Some(i32, !),
  None
}

fn panic() -> ! { panic!() }

let x = Some(42, panic());

into MIR like

let x: Option2;
x.Some.0 = 42;
x.Some.1 = panic();
SetDiscriminant(x, Some);

and then we would downcast to an uninhabited variant.

So I'm perfectly fine with allowing such downcasts, the reason I added the assertion was so that we'd know when they actually happen.

Would be good to have something like the above as a custom MIR test.

@tmiasko
Copy link
Contributor

tmiasko commented Dec 12, 2023

The fact that the coroutine variant has an uninhabited ABI in the first place
is also incorrect. Coroutine saved locals are potentially uninitialized, so
they shouldn't infect the whole variant. This can be turned into a
miscompilation.

The prefix layout already uses Ty::new_maybe_uninit. The same should presumably
apply to fields inside variants.

@RalfJung
Copy link
Member

This can be turned into a miscompilation.

Can it? So far we haven't even be able to turn this into UB, let alone a miscompilation. Causing UB would require a generator to yield when it is in one of these variants that is considered uninhabited. Is that possible?

@tmiasko
Copy link
Contributor

tmiasko commented Dec 12, 2023

This can be turned into a miscompilation.

Can it? So far we haven't even be able to turn this into UB, let alone a miscompilation. Causing UB would require a generator to yield when it is in one of these variants that is considered uninhabited. Is that possible?

Introduce a local that is alive across yield, but make the initialization conditional (the fact that a prefix part is handled correctly also complicates the situation somewhat).

$ rustc --edition=2021 a.rs && ./a
Illegal instruction
a.rs
#![feature(never_type)]
#![feature(noop_waker)]
#![feature(rustc_attrs)]
use std::pin::Pin;
use std::future::Future;
use std::mem::ManuallyDrop;
use std::task::*;

pub async fn f<T>(x: bool, y: bool) {
    if y {
        let b : ManuallyDrop<T>;
        let c : *const ManuallyDrop<T>;
        if x {
            b = make::<ManuallyDrop<T>>();
            c = &b;
        }
        Wait.await;
    } else {
        let b : ManuallyDrop<T>;
        let c : *const ManuallyDrop<T>;
        if x {
            b = make::<ManuallyDrop<T>>();
            c = &b;
        }
        Wait.await;
    }
}

pub struct Wait;

impl Future for Wait {
    type Output = ();
    fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<()> {
        Poll::Pending
    }
}

pub fn make<T>() -> T {
    loop {}
}

fn main() {
    let waker = std::task::Waker::noop();
    let mut ctx = std::task::Context::from_waker(&waker);
    let f = std::pin::pin!(f::<!>(false, true));
    let _ = f.poll(&mut ctx);
}

@tmiasko tmiasko added I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness A-coroutines Area: Coroutines A-layout Area: Memory layout of types labels Dec 12, 2023
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Dec 12, 2023
@apiraino
Copy link
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-high

@rustbot rustbot added P-high High priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Dec 12, 2023
@tmiasko
Copy link
Contributor

tmiasko commented Dec 12, 2023

The incorrect layout will be fixed by #118871.

@RalfJung
Copy link
Member

Introduce a local that is alive across yield, but make the initialization conditional (the fact that a prefix part is handled correctly also complicates the situation somewhat).

Wow, good catch!

@saethlin, what does Miri with your PR do on that example?

I wonder where the unreachable comes from here in codegen, since we are not moving around the future by-value.

@tmiasko
Copy link
Contributor

tmiasko commented Dec 12, 2023

I wonder where the unreachable comes from here in codegen, since we are not moving around the future by-value.

It is an llvm.trap generated for SetDiscriminant when switching to an uninhabited variant.

@RalfJung
Copy link
Member

Ah, I see. That's good then, Miri also explicitly checks that and triggers UB.

@saethlin
Copy link
Member Author

With the assertion removed indeed, we get this:

error: Undefined Behavior: writing discriminant of an uninhabited enum variant
  --> src/main.rs:14:14
   |
14 |         Wait.await;
   |              ^^^^^ writing discriminant of an uninhabited enum variant
   |

@RalfJung
Copy link
Member

Great. :) We should definitely have this as a testcase once #118871 lands.

I assume the ICE will also be gone then. We could still decide to remove the check in Miri, since arguably the example I gave here should work -- but we can also keep it for now since after all it has found a real bug...

saethlin added a commit to saethlin/rust that referenced this issue Dec 14, 2023
@saethlin saethlin linked a pull request Dec 14, 2023 that will close this issue
@RalfJung
Copy link
Member

With #118871 having landed, the example no longer ICEs.

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Dec 14, 2023
…thlin

interpret: extend comment on the inhabitedness check in downcast

Cc rust-lang#115145
r? `@saethlin`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 14, 2023
…thlin

interpret: extend comment on the inhabitedness check in downcast

Cc rust-lang#115145
r? ``@saethlin``
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Dec 14, 2023
Rollup merge of rust-lang#118935 - RalfJung:interpret-downcast, r=saethlin

interpret: extend comment on the inhabitedness check in downcast

Cc rust-lang#115145
r? ``@saethlin``
@saethlin
Copy link
Member Author

ICE is fixed and regression tests have landed.

@saethlin saethlin removed their assignment Dec 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-coroutines Area: Coroutines A-layout Area: Memory layout of types C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-high High priority S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants