Description
We found this issue while integrating recent upstream changes into ferrocene.
The easiest way to reproduce the issue is with the following Cargo project.
Cargo.toml
[package]
name = "repro"
edition = "2024"
[target.aarch64-unknown-none.dependencies]
semihosting.version = "=0.1.20"
semihosting.features = ["stdio", "panic-handler"]
.cargo/config.toml
[target.aarch64-unknown-none]
runner = "qemu-aarch64-static" # `qemu-aarch64` should also work
src/main.rs
#![allow(incomplete_features)]
#![cfg_attr(target_arch = "aarch64", no_main)]
#![cfg_attr(target_arch = "aarch64", no_std)]
#![feature(async_drop, impl_trait_in_assoc_type)]
use core::future::{self, AsyncDrop};
use core::mem;
use core::pin::{Pin, pin};
#[cfg(target_arch = "aarch64")]
use semihosting::println;
#[cfg_attr(target_arch = "aarch64", unsafe(export_name = "_start"))]
fn main() {
test_async_drop(AsyncStruct {
b: AsyncInt(8),
a: AsyncInt(7),
i: 6,
});
#[cfg(target_arch = "aarch64")]
semihosting::process::exit(0);
}
fn test_async_drop<T>(x: T) {
let mut x = mem::MaybeUninit::new(x);
let dtor = pin!(unsafe { future::async_drop_in_place(x.as_mut_ptr()) });
println!("{}", mem::size_of_val(&*dtor));
}
#[allow(dead_code)]
struct AsyncInt(i32);
impl Drop for AsyncInt {
fn drop(&mut self) {}
}
impl AsyncDrop for AsyncInt {
async fn drop(self: Pin<&mut Self>) {}
}
#[allow(dead_code)]
struct AsyncStruct {
i: i32,
a: AsyncInt,
b: AsyncInt,
}
impl Drop for AsyncStruct {
fn drop(&mut self) {}
}
impl AsyncDrop for AsyncStruct {
async fn drop(self: Pin<&mut Self>) {}
}
If you run this on a x86_64 host then you get the value 168 which is what the test expects
$ cargo run
168
If you compile to aarch64-unknown-none
and run the program in QEMU you get the value 136.
$ cargo run --target aarch64-unknown-none
136
The difference might be that the aarch64-unknown-none
target is a panic=abort
(non-unwinding) target so the size of the coroutine is different due to the lack of drop flags or landing pads.
Note that both targets have 64-bit pointer which is what the UI test uses as the only criteria to execute the assertion or not.
Were are not exactly sure which recent PR broke the test as it was passing before but it should be one of the PRs listed in ferrocene/ferrocene#1459 (comment)
Meta
rustc --version --verbose
:
rustc --version --verbose
rustc 1.89.0-nightly (ce7e97f73 2025-05-11)
binary: rustc
commit-hash: ce7e97f7371af47e0786f74aa169f6ac9473ff4e
commit-date: 2025-05-11
host: x86_64-unknown-linux-gnu
release: 1.89.0-nightly
LLVM version: 20.1.4