Skip to content

Root-cause iterator-simple stuck state after drop-glue support#1066

Draft
Stevengre wants to merge 2 commits into
codex/fix-interior-mut-drop-gluefrom
remove-bridge-rules
Draft

Root-cause iterator-simple stuck state after drop-glue support#1066
Stevengre wants to merge 2 commits into
codex/fix-interior-mut-drop-gluefrom
remove-bridge-rules

Conversation

@Stevengre

@Stevengre Stevengre commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Adding drop function (drop_in_place) support caused iterator-simple to get stuck during proof. This PR investigates the root cause and applies a structural fix rather than papering over the symptoms with temporary bridge rules.

Root cause

When dropping IntoIter (which contains [MaybeUninit<T>; N]), PtrToPtr casts append type-projection projections to a pointer's PLACEPROJ:

PLACEPROJ = base_projs  CI(0,0,false)  Field(1,MU)  Field(0,MD)
                         └── array→element ──── MaybeUninit → T ──┘

When a deref rule later appends PointerOffset(N) at the end via appendP, the traversal order becomes:

base → CI(0) enters element 0 → Fields unwrap MU → T value → PO(N) → STUCK

PointerOffset expects a Range (array) but receives a scalar T. The correct semantic order is PointerOffset first (array-level element selection), then type projection (per-element type conversion).

Fix: insertPOBeforeTypeProj

Instead of blindly appending PointerOffset at the end of PLACEPROJ, the new insertPOBeforeTypeProj function scans the projection list for CI(0, 0, false) — the distinctive marker of type projections from PtrToPtr casts (normal MIR ConstantIndex uses non-zero array lengths) — and merges the pointer offset into it: CI(0+OFF, 0, false).

This produces the correct traversal:

base → CI(OFF,0,false) enters element at offset → Fields unwrap MU → T value ✓

When no CI(0,0,false) is found, it falls back to appending PointerOffset at the end (preserving existing behavior for non-PtrToPtr cases).

Other changes

  • Fix Subslice projected type (_projected_ty): compute the correct result array length from Subslice parameters
  • Remove removeIndexTail-related workaround from RawPtr aggregate construction
  • Remove the consP HACK rule: no longer the primary mechanism (kept as optimization)
  • Remove the two temporary bridge rules (Union-unwrap for Field on Range, bare-value-to-Range for PointerOffset)
  • Restore iterator-simple as a passing test

Test plan

  • iterator-simple passes (restored from unsupported-fail)
  • subslice-drop-unsupported-fail passes as expected-fail
  • Subslice _projected_ty unit test passes
  • No other integration tests regress
  • make check passes
  • K build succeeds (verified locally)

🤖 Generated with Claude Code

Remove the two temporary bridge rules added for the drop-glue
path. The bare-value-to-Range wrapper for PointerOffset and
the Union-unwrap for Field on Range are symptoms of a deeper
design issue in how #typeProjection stores per-element type
projections in PLACEPROJ for slice-to-slice PtrToPtr casts,
which conflicts with PointerOffset positioning.

The Union-unwrap rule parallels the existing Aggregate-unwrap
rule (line 503-509) but was added as a workaround rather than
addressing the root cause. The bare-to-Range rule papered over
PointerOffset receiving non-Range values.

Both are tracked in #1011 for a proper structural fix.
With the bridge rules removed, iterator-simple gets stuck on
Range(ListItem(Union(...))) + Field projection, exposing the
#typeProjection design issue tracked in #1011.

Rename to -unsupported-fail and add show snapshot.
@Stevengre Stevengre marked this pull request as draft April 16, 2026 10:08
@Stevengre Stevengre changed the title Remove temporary bridge rules from #traverseProjection Root-cause iterator-simple stuck state after drop-glue support Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant