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

internal compiler error: thread 'rustc' panicked at 'Box<dyn Any>' #95406

Closed
nwalfield opened this issue Mar 28, 2022 · 7 comments
Closed

internal compiler error: thread 'rustc' panicked at 'Box<dyn Any>' #95406

nwalfield opened this issue Mar 28, 2022 · 7 comments
Labels
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.

Comments

@nwalfield
Copy link

Code

You can find a small example in the gitlab repo.

The relevant code is:

macro_rules! ffi {
    // $Crt is the C function's return type.  It must be possible to
    // convert an Error value v of type $rt to a value of type $Crt by doing:
    // $Crt::from($rt).
    //
    // $ok is the value (of type $rt) to map Ok to.
    (fn $f:ident($($v:ident: $t:ty),*)
        -> Result<$rt:ty, $et:ty>
        -> ($Crt:ty; $rt_to_crt:expr; $err_to_crt: expr)
        $body:block
     ) =>
    {
        // The wrapper.  It calls $f and turns the result into an
        // error code.
        #[allow(unused)]
        #[no_mangle] pub extern "C"
        fn $f($($v: $t),*) -> $Crt {
            // The actual function.
            fn inner($($v: $t),*) -> std::result::Result<$rt, $et> { $body }

            // We use AssertUnwindSafe.  This is safe, because if we
            // catch a panic, we abort.  If we turn the panic into an
            // error, then we need to reexamine this assumption.
            let r = std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
                match inner($($v,)*) {
                    Ok(v) => {
                        let rt: $Crt = $rt_to_crt(v);
                        rt
                    }
                    Err(err) => {

                        let rt: $Crt = $err_to_crt(err);
                        rt
                    }
                }
            }));
            match r {
                Ok(code) => code,
                Err(_) => {
                    unsafe { ::libc::abort() };
                }
            }
        }
    }
}

ffi!(fn pgpSignatureType(dig: *const c_int)
     -> Result<c_int, crate::Error>
     -> (c_int;
         |v| {
             v
         };
         |_| -1)
{
    panic!();
});

When I try to inline the ffi! macro invocation, the error goes away (see my commented example for my attempt).

Meta

In my rust-roolchain file, I have
1.59.0. It works fine with 1.56.1.

Error output

   Compiling rpm-sequoia v0.1.0 (/home/us/neal/work/pep/rpm-sequoia)
error: internal compiler error: compiler/rustc_codegen_llvm/src/context.rs:867:13: failed to get layout for `[type error]`: the type `[type error]` has an unknown layout
   --> src/lib.rs:58:22
    |
58  |           #[no_mangle] pub extern "C"
    |  ______________________^
59  | |         fn $f($($v: $t),*) -> $Crt {
    | |__________________________________^
...
120 | / ffi!(fn pgpSignatureType(dig: *const c_int)
121 | |      -> Result<c_int, crate::Error>
122 | |      -> (c_int;
123 | |          |v| {
...   |
128 | |     panic!();
129 | | });
    | |__- in this macro invocation
    |
    = note: this error: internal compiler error originates in the macro `ffi` (in Nightly builds, run with -Z macro-backtrace for more info)

thread 'rustc' panicked at 'Box<dyn Any>', /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/compiler/rustc_errors/src/lib.rs:1115:9
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: std::panic::panic_any::<rustc_errors::ExplicitBug>
   2: <rustc_errors::HandlerInner>::span_bug::<rustc_span::span_encoding::Span>
   3: <rustc_errors::Handler>::span_bug::<rustc_span::span_encoding::Span>
   4: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, ()>
   5: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
   6: rustc_middle::util::bug::span_bug_fmt::<rustc_span::span_encoding::Span>
   7: <rustc_codegen_llvm::context::CodegenCx as rustc_middle::ty::layout::LayoutOfHelpers>::handle_layout_err
   8: <rustc_codegen_llvm::context::CodegenCx as rustc_middle::ty::layout::LayoutOf>::spanned_layout_of::{closure#0}
   9: rustc_codegen_ssa::mir::analyze::non_ssa_locals::<rustc_codegen_llvm::builder::Builder>
  10: rustc_codegen_ssa::mir::codegen_mir::<rustc_codegen_llvm::builder::Builder>
  11: rustc_codegen_llvm::base::compile_codegen_unit::module_codegen
  12: rustc_codegen_llvm::base::compile_codegen_unit
  13: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  14: <rustc_session::session::Session>::time::<alloc::boxed::Box<dyn core::any::Any>, rustc_interface::passes::start_codegen::{closure#0}>
  15: <rustc_interface::queries::Queries>::ongoing_codegen
  16: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorReported>>
  17: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
  18: rustc_interface::interface::create_compiler_and_run::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>
  19: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.59.0 (9d1b2106e 2022-02-23) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental --crate-type cdylib

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

query stack during panic:
end of query stack
error: could not compile `rpm-sequoia`
@nwalfield nwalfield 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 Mar 28, 2022
@b-ncMN
Copy link
Contributor

b-ncMN commented Mar 28, 2022

I think this has been fixed in #94438

@nwalfield
Copy link
Author

The above code works with 1.56.0. The ICE appeared in 1.57.0 and is still present in rustc 1.61.0-nightly (ee915c34e 2022-03-28).

@nwalfield
Copy link
Author

nwalfield commented Apr 5, 2022

I have a somewhat small demo and I've narrow it down to a single line of code: when the closure, which is passed a marco expr is called I get the ICE. When I replace that line of code with a panic!(), the code compiles:

macro_rules! ffi {
    // $Crt is the C function's return type.  It must be possible to
    // convert an Error value v of type $rt to a value of type $Crt by doing:
    // $Crt::from($rt).
    //
    // $ok is the value (of type $rt) to map Ok to.
    (fn $f:ident($($v:ident: $t:ty),*)
        -> Result<$rt:ty, $et:ty>
        -> ($Crt:ty; $rt_to_crt:expr; $err_to_crt: expr)
        $body:block
     ) =>
    {
        // The wrapper.  It calls $f and turns the result into an
        // error code.
        #[allow(unused)]
        #[no_mangle] pub extern "C"
        fn $f($($v: $t),*) -> $Crt {
            // The actual function.
            let inner = |$($v: $t),*| -> std::result::Result<$rt, $et> { $body };

            match inner($($v,)*) {
                Ok(v) => {
                    // XXX: Replace this line with a panic! and the ICE goes away.
                    let rt: $Crt = $rt_to_crt(v);
                    rt
                    // panic!();
                }
                Err(err) => {
                    let rt: $Crt = $err_to_crt(err);
                    rt
                }
            }
        }
    }
}

@nwalfield
Copy link
Author

Here's an even small demo with 3 ways to avoid the ICE:

use libc::c_int;

// XXX: Remove '; $err_to_crt:expr' and the ICE goes away.
//
// -> ($Crt:ty; $rt_to_crt:expr)
macro_rules! ffi {
    (fn $f:ident()
        -> Result<$rt:ty, $et:ty>
        -> ($Crt:ty; $rt_to_crt:expr; $err_to_crt:expr)
        $body:block
     ) =>
    {
        #[no_mangle] pub extern "C"
        fn $f() -> $Crt {
            // XXX: OR Replace this line with 0 and the ICE goes away.
            let rt: $Crt = $rt_to_crt(1i32);
            rt
            // 0
        }
    }
}

fn id(v: c_int) -> c_int { v }

ffi!(fn pgpSignatureType()
     -> Result<c_int, crate::Error>
     -> (c_int;
         // XXX: OR: Replace this closure with a function:
         |v| -> c_int { v };
         // id;
         |_| -1)
{
    panic!();
});

It appears that the underlying bug has something to do with how closures are handled.

@inquisitivecrystal
Copy link
Contributor

I was looking at this, in an attempt to fix it, and it seems that it's already been fixed on nightly. The fix bisects to #103398, which is a rollup, but it seems like the fix was almost certainly in PR #103224. I'm not even sure if we need to add a test; the test added by that PR covered a very similar case.

@inquisitivecrystal
Copy link
Contributor

Closing as fixed by #103224 on nightly, with an appropriate test being added by the same PR. Feel free to reopen if more work is needed.

@nwalfield
Copy link
Author

Thanks for taking a look!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
Development

No branches or pull requests

3 participants