Skip to content

UI test async-drop-initial now fails size assertion on aarch64-unknown-none #140939

Closed
@japaric

Description

@japaric
Member

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

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on May 12, 2025
japaric

japaric commented on May 12, 2025

@japaric
MemberAuthor

after bisecting:

The last good nightly was nightly-2025-04-28 (cb31a009e 2025-04-27). There, both targets report a size of 1376.

The first bad nightly is nightly-2025-04-29 (25cdf1f67 2025-04-28). That's where we start seeing the 168 vs 136 divergence.

The most relevant PR between those two nightlies is PR #123948 (cc @azhogin) . That PR also changed the expected values in the UI test.

japaric

japaric commented on May 12, 2025

@japaric
MemberAuthor

The reported size changes if one switches from panic=unwind to panic=abort. This can be confirmed in the repro with the following change in the Cargo.toml

[profile.dev]
panic = "abort"

With this change the reported size becomes 136 which matches the value of the aarch64-unknown-none target, a target that defaults to panic=abort as seen below

$ rustc +nightly -Z unstable-options --print target-spec-json --target aarch64-unknown-none | rg panic
  "panic-strategy": "abort",
added 3 commits that reference this issue on May 12, 2025
05d012c
91f45e0
2fdf3d9
japaric

japaric commented on May 12, 2025

@japaric
MemberAuthor

submitted a fix in #140941

petrochenkov

petrochenkov commented on May 12, 2025

@petrochenkov
Contributor

Duplicate of #140493.

added a commit that references this issue on May 12, 2025

Auto merge of rust-lang#140941 - ferrocene:ja/gh140939-fix-async-drop…

a4800b9
added
A-testsuiteArea: The testsuite used to check the correctness of rustc
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
O-AArch64Armv8-A or later processors in AArch64 mode
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on May 12, 2025
added a commit that references this issue on May 12, 2025

Auto merge of rust-lang#140941 - ferrocene:ja/gh140939-fix-async-drop…

420ca71
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-testsuiteArea: The testsuite used to check the correctness of rustcC-bugCategory: This is a bug.F-async_drop`#![feature(async_drop)]`O-AArch64Armv8-A or later processors in AArch64 modeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @japaric@petrochenkov@jieyouxu@rustbot

      Issue actions

        UI test async-drop-initial now fails size assertion on `aarch64-unknown-none` · Issue #140939 · rust-lang/rust