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>, interner: DbInterner<'db>,
sizedness: SizedTraitKind, sizedness: SizedTraitKind,
) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> { ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
if self.is_struct() { let tail_ty = self.struct_tail_ty(interner)?;
let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?; tail_ty
.map_bound(|tail_ty| sizedness_constraint_for_ty(interner, sizedness, tail_ty))
let constraint_ty = sizedness_constraint_for_ty(interner, sizedness, tail_ty)?; .transpose()
Some(EarlyBinder::bind(constraint_ty))
} else {
None
}
} }
fn destructor( fn destructor(

View file

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