Skip to content

Nested transparent wrapper pointer casts produce incorrect projection chains #997

@Stevengre

Description

@Stevengre

Problem

Pointer casts involving nested transparent wrappers around arrays (e.g., *const [u8; 2] → *const W2(W1([u8; 2]))) produce incorrect projection chains that get stuck during traversal.

The #pointeeProjection function's source-first strategy correctly handles single-layer wrappers via the lookupTy(FIELD) ==K SRC guard, but for nested wrappers the immediate inner type doesn't match the source array, so the guard fails and the array unwrap fires first, producing an uncancelable projectionElemSingletonArray tail.

Reproducer

#[derive(Clone, Copy)]
struct W1([u8; 2]);

#[derive(Clone, Copy)]
struct W2(W1);

fn main() {
    let arr: [u8; 2] = [11, 22];
    let w: W2 = unsafe { *((&arr) as *const [u8; 2] as *const W2) };
    assert_eq!((w.0).0, [11, 22]);
}

Running kmir prove on this program produces 2 stuck nodes (one from the alignment check ND branch per #638, and one from the bad projection chain).

Root Cause

In types.md, the specialized rule:

rule #pointeeProjection(SRC:TypeInfo, typeInfoStructType(_NAME, _ADTDEF, FIELD .Tys, LAYOUT))
    => maybeConcatProj(projectionElemWrapStruct, #pointeeProjection(SRC, lookupTy(FIELD)))
    requires #isArrayType(SRC) andBool #zeroFieldOffset(LAYOUT) andBool lookupTy(FIELD) ==K SRC
    [priority(42)]

Only matches when the struct's immediate inner type equals the source. For W2(W1([u8;2])), lookupTy(FIELD) returns W1_info ≠ [u8;2]_info, so the guard fails.

The correct projection for this cast would be WrapStruct + WrapStruct (wrap into W1, then into W2), which requires multi-level lookahead that the current one-step guard cannot provide.

Status

This is a pre-existing bug — it also fails on master (before PR #988's source-first refactoring). The source-first strategy did not introduce this regression.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions