Skip to content

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

Open

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.

Activity

  1. feliperodri commented on Aug 25, 2026

    @feliperodri
    MemberAuthor

    Surfaced by #4760 (the nightly-2026-06-01 upgrade), which weakens the assertion to a non-null check on the slot.

  2. added theissue type on Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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