mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-12-23 08:48:08 +00:00
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:
parent
d4f45d7ae2
commit
3172d19886
3 changed files with 36 additions and 14 deletions
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue