mir_transform: prohibit scalable vectors in async

Scalable vectors cannot be members of ADTs and thus cannot be kept over
await points in async functions.
This commit is contained in:
David Wood 2025-07-10 06:18:13 +00:00
parent 89eea57594
commit 4185e9f2ec
No known key found for this signature in database
3 changed files with 62 additions and 0 deletions

View file

@ -1891,6 +1891,16 @@ fn check_must_not_suspend_ty<'tcx>(
SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data },
)
}
// FIXME(sized_hierarchy): This should be replaced with a requirement that types in
// coroutines implement `const Sized`. Scalable vectors are temporarily `Sized` while
// `feature(sized_hierarchy)` is not fully implemented, but in practice are
// non-`const Sized` and so do not have a known size at compilation time. Layout computation
// for a coroutine containing scalable vectors would be incorrect.
ty::Adt(def, _) if def.repr().scalable() => {
tcx.dcx()
.span_err(data.source_span, "scalable vectors cannot be held over await points");
true
}
ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),
// FIXME: support adding the attribute to TAITs
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {

View file

@ -0,0 +1,44 @@
//@ only-aarch64
//@ edition:2021
#![allow(incomplete_features, internal_features)]
#![feature(
core_intrinsics,
simd_ffi,
rustc_attrs,
link_llvm_intrinsics
)]
use core::intrinsics::transmute_unchecked;
#[rustc_scalable_vector(4)]
#[allow(non_camel_case_types)]
pub struct svint32_t(i32);
#[target_feature(enable = "sve")]
pub unsafe fn svdup_n_s32(op: i32) -> svint32_t {
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")]
fn _svdup_n_s32(op: i32) -> svint32_t;
}
unsafe { _svdup_n_s32(op) }
}
#[target_feature(enable = "sve")]
async fn another() -> i32 {
42
}
#[no_mangle]
#[target_feature(enable = "sve")]
pub async fn test_function() {
unsafe {
let x = svdup_n_s32(1); //~ ERROR: scalable vectors cannot be held over await points
let temp = another().await;
let y: svint32_t = transmute_unchecked(x);
}
}
fn main() {
let _ = unsafe { test_function() };
}

View file

@ -0,0 +1,8 @@
error: scalable vectors cannot be held over await points
--> $DIR/async.rs:36:13
|
LL | let x = svdup_n_s32(1);
| ^
error: aborting due to 1 previous error