Don't implement sizedness check via all_field_tys()

Since we don't implement it currently for perf reasons, but here we only need a struct's tail field, it will be wrong.
This commit is contained in:
Chayim Refael Friedman 2025-12-06 21:23:21 +02:00
parent d4f45d7ae2
commit 3172d19886
3 changed files with 36 additions and 14 deletions

View file

@ -690,15 +690,10 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
interner: DbInterner<'db>,
sizedness: SizedTraitKind,
) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
if self.is_struct() {
let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?;
let constraint_ty = sizedness_constraint_for_ty(interner, sizedness, tail_ty)?;
Some(EarlyBinder::bind(constraint_ty))
} else {
None
}
let tail_ty = self.struct_tail_ty(interner)?;
tail_ty
.map_bound(|tail_ty| sizedness_constraint_for_ty(interner, sizedness, tail_ty))
.transpose()
}
fn destructor(

View file

@ -422,12 +422,10 @@ pub fn sizedness_constraint_for_ty<'db>(
.next_back()
.and_then(|ty| sizedness_constraint_for_ty(interner, sizedness, ty)),
Adt(adt, args) => {
let tail_ty =
EarlyBinder::bind(adt.all_field_tys(interner).skip_binder().into_iter().last()?)
.instantiate(interner, args);
Adt(adt, args) => adt.struct_tail_ty(interner).and_then(|tail_ty| {
let tail_ty = tail_ty.instantiate(interner, args);
sizedness_constraint_for_ty(interner, sizedness, tail_ty)
}
}),
Placeholder(..) | Bound(..) | Infer(..) => {
panic!("unexpected type `{ty:?}` in sizedness_constraint_for_ty")

View file

@ -2229,3 +2229,32 @@ fn test(x: *mut u8) {
"#,
);
}
#[test]
fn unsized_struct() {
check_types(
r#"
//- minicore: sized, phantom_data
use core::marker::PhantomData;
const UI_DEV_CREATE: Ioctl = Ioctl(PhantomData);
struct Ioctl<T: ?Sized = NoArgs>(PhantomData<T>);
struct NoArgs([u8]);
impl<T> Ioctl<T> {
fn ioctl(self) {}
}
impl Ioctl<NoArgs> {
fn ioctl(self) -> u32 { 0 }
}
fn main() {
UI_DEV_CREATE.ioctl();
// ^^^^^^^^^^^^^^^^^^^^^ u32
}
"#,
);
}