Skip to content

vtable_size_align_drop no longer checks the drop slot holds the right type's drop glue #4759

Description

@feliperodri

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 Drop impl (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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    [C] BugThis is a bug. Something isn't working.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions