Repository navigation
internal compiler error: thread 'rustc' panicked at 'Box<dyn Any>' #95406
Description
Activity
- addedC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Mar 28, 2022 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).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
expris called I get the ICE. When I replace that line of code with apanic!(), 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 } } } } }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 commented
on Dec 12, 2022 ContributorMore actionsI 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 commented
on Dec 16, 2022 ContributorMore actionsClosing 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.
Thanks for taking a look!
Reacted by inquisitivecrystal
Code
You can find a small example in the gitlab repo.
The relevant code is:
When I try to inline the
ffi!macro invocation, the error goes away (see my commented example for my attempt).Meta
In my
rust-roolchainfile, I have1.59.0. It works fine with 1.56.1.
Error output