Repository navigation
vtable_size_align_drop no longer checks the drop slot holds the right type's drop glue #4759
Description
Context
tests/kani/DynTrait/vtable_size_align_drop.rs reads a vtable's raw layout through the pointer-metadata API and asserts each of the three header slots:
assert!(drop_from_vtable(vtable_ptr) == drop_in_place::<Sheep> as *mut ());
assert!(size_from_vtable(vtable_ptr) == size_of::<i32>());
assert!(align_from_vtable(vtable_ptr) == size_of::<i32>());Problem
As of nightly-2026-06-01 (#4757) the drop-glue shim that rustc places in the vtable's first slot is core::ptr::drop_glue::<T>, not core::ptr::drop_in_place::<T>. Traced with Kani's own debug logging on codegen_vtable_drop_in_place:
drop_instance=Instance { kind: Shim, def: "_RINvNtCs..._4core3ptr9drop_glueNtCs..._5probe5SheepEBD_", .. }
Kani puts the right thing in the slot — Instance::resolve_drop_in_place(T)'s mangled symbol — but that is now a different function from the user-callable core::ptr::drop_in_place::<T> that the test compares against, and drop_glue is not nameable from Rust source. Confirmed with cover checks that the vtable slot and drop_in_place::<T> are provably distinct for both of the test's types.
Note the vtable layout is unchanged: COMMON_VTABLE_ENTRIES is still [MetadataDropInPlace, MetadataSize, MetadataAlign] with the drop pointer at index 0. Only the identity of the function in that slot changed.
This was verified to be a genuine nightly-2026-06-01 regression rather than a pre-existing fragility: rebuilding the parent commit against nightly-2026-05-01 passes.
What #4757 did
Since the test's stated purpose is the size and align fields (it is named for them, and those use the public DynMetadata::size_of()/align_of() API), #4757 replaced the two exact-identity assertions with a non-null check on the slot, with a comment explaining why:
assert!(!drop_from_vtable(vtable_ptr).is_null());Why this is worth tracking
The weaker assertion no longer checks that the slot holds the drop glue for the right type — a codegen bug that put another type's drop glue (or any other function pointer) in the slot would now pass. Restoring that coverage needs a way to name the drop-glue shim, or to compare against it indirectly. Options:
- Compare the drop slots of two different concrete types for inequality, plus check each is non-null — cheap, and would catch a slot that is shared or misassigned across types.
- Call through the slot and observe a side effect from a type with a real
Dropimpl (the current test types have no drop glue), which would check the pointer actually dispatches to that type's destructor. - A Kani-internal hook exposing the resolved drop-glue symbol for test purposes.
The second option looks the most valuable: it verifies the slot is callable and correct rather than merely present, and does not depend on any rustc-internal naming.
Activity
feliperodri commentedon Aug 25, 2026
Surfaced by #4760 (the
nightly-2026-06-01upgrade), which weakens the assertion to a non-null check on the slot.Upgrade Rust toolchain to nightly-2026-06-01 (model-checking#4760)