Conversation
0577e22 to
f2ccd0c
Compare
|
These two |
|
I re-ran Command used:
Results:
The failures are not generic snapshot drift. They get stuck in different places:
This is the case that needs the
That is, after unwrapping the So the effect of the two rules is complementary:
In other words, after this PR starts executing real drop glue, The longer-term cleanup is still tracked in #1011, but based on this comparison these two rules are doing necessary work in PR #999 rather than just papering over an unrelated difference. |
|
I ran the same kind of A/B check for Commands used:
Results:
So unlike the two The likely reason is that, in the current PR, the only explicit producer of But the drop glue functions we are actually exercising here return Based on these runs, |
|
One more note on Its job is to handle return paths where the caller intentionally does not consume the callee's return value. In KMIR that case is represented by the sentinel destination: Without but I confirmed this is not just theoretical: after removing So the purpose of the rule is simply: if the destination is the ignored-return sentinel, skip writeback and continue directly to the caller's target block. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dafd5f50b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce96db106e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ce96db1 to
71e9f53
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0950dccd96
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae3e60adb6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
dkcumming
left a comment
There was a problem hiding this comment.
I like what you have here. But there are the concerns I mention in the comments. But aside from that I do wonder if this would be a good addition in the SmirJson, there could be a field added for drop_functions, and it could be populated as part of visiting a TerminatorKind::Drop. Upstream Rust does not serialise this, but we can add a side table if it would be useful. Would save doing it in python and might be useful for others.
I would like the opinion of @jberthold if you have time
| // Temporary bridge rule: after PointerOffset lifts a single value to Range(ListItem(...)), | ||
| // unwrap a Union head element so the existing Union + Field rules below can keep running. | ||
| rule <k> #traverseProjection( | ||
| DEST, | ||
| Range(ListItem(Union(_, _) #as VALUE) _REST:List), | ||
| projectionElemField(IDX, TY) PROJS, | ||
| CTXTS | ||
| ) | ||
| => #traverseProjection(DEST, VALUE, projectionElemField(IDX, TY) PROJS, CTXTS) ... </k> // TODO mark context? | ||
| [preserves-definedness, priority(100)] |
There was a problem hiding this comment.
I am concerned to add these temporary rules. I feel getting these mix ups with the projections is indicative that we are handing the pointers wrong, and by adding rules like this we suppress the underlying problem. I know they are temporary, but a bandaid added and forgotten could cause deep confusion later...
There was a problem hiding this comment.
I agree with the concern, and I do not want these bridge rules to become permanent sediment.
For this PR they are only meant as a narrow regression fix for the newly exercised drop-glue path. I opened follow-up issue #1011 to track the real cleanup: #1011
The plan there is to refactor #traverseProjection around a single representation invariant and then delete these round-trip bridge rules rather than leave them in place indefinitely.
There was a problem hiding this comment.
Agree with both, requiring this rule indicates a problem with how pointers are handled. It is specialised to Union and Field but maybe it applies more generally?
I think this could make sense as a separate upstream improvement, but I would prefer to keep it out of #999. My current view is that So I would prefer to treat that as a follow-up design discussion or separate issue/PR rather than fold it into this one. |
| // Temporary bridge rule: after PointerOffset lifts a single value to Range(ListItem(...)), | ||
| // unwrap a Union head element so the existing Union + Field rules below can keep running. | ||
| rule <k> #traverseProjection( | ||
| DEST, | ||
| Range(ListItem(Union(_, _) #as VALUE) _REST:List), | ||
| projectionElemField(IDX, TY) PROJS, | ||
| CTXTS | ||
| ) | ||
| => #traverseProjection(DEST, VALUE, projectionElemField(IDX, TY) PROJS, CTXTS) ... </k> // TODO mark context? | ||
| [preserves-definedness, priority(100)] |
There was a problem hiding this comment.
Agree with both, requiring this rule indicates a problem with how pointers are handled. It is specialised to Union and Field but maybe it applies more generally?
058ed6d to
cada2a8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9821acb11a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
c0bc575 to
c7c7548
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7c7548ab6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The two bridge rules added in bed3503 (Union-unwrap for Field, and bare-value-to-Range for PointerOffset) treated a symptom rather than the root cause. The real issue is in how removeIndexTail and #typeProjection interact during pointer construction and PtrToPtr casts for slice types. Removing these rules exposes the underlying stuck state so the proper fix can be validated against it. See #1011 for the planned structural fix.
The iterator-simple test exposes a stuck state in #traverseProjection caused by the interaction between removeIndexTail and #typeProjection for slice-of-MaybeUninit pointer casts. Mark as -fail with show snapshot until the root cause in pointer projection construction is resolved. See #1011.
The consP rule that merged ConstantIndex with PointerOffset was a workaround for a deeper issue: removeIndexTail in #mkAggregate(aggregateKindRawPtr) strips the element-extraction CI(0) when constructing fat pointers from thin pointers, but #typeProjection later adds per-element navigation projections (Field for MaybeUninit→ManuallyDrop→T) that assume the element has already been extracted. Removing removeIndexTail preserves the CI(0) through the fat pointer construction, allowing the subsequent #typeProjection projections to correctly navigate into individual array elements. The consP HACK rule is also removed as it is no longer needed and was conceptually unsound (merging projections from different semantic levels). The iterator-simple test now reaches a different stuck state: PointerOffset(1,0) applied to a scalar Integer after successful element navigation, which is closer to the real remaining issue (projection ordering between CI and PointerOffset). See #1011.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 60b5e5a842
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
c7e3a5d to
575b6ed
Compare
Add integration test for Subslice projection on an owned array of Drop types. The `let [first, rest @ ..]` pattern generates a Subslice that changes the type from [Droppable; 3] to [Droppable; 2], exercising an unsupported code path in _projected_ty() and K semantics. Marked as expected-fail with show snapshot.
575b6ed to
8c27c7e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c27c7e9a6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Revert the experimental removal of bridge rules, consP HACK rule, and removeIndexTail. These are workarounds for a deeper design issue in how #typeProjection interacts with PointerOffset for slice-to-slice PtrToPtr casts (tracked in #1011), and removing them without the proper fix causes regressions. Restore iterator-simple.rs as a passing test.
Add unit test demonstrating that _projected_ty() returns the original array type for Subslice projections, causing call_edges to miss the drop_in_place::<[T; M]> edge and reduce_to() to incorrectly prune the required drop glue. Add integration test subslice-drop-partial-move.rs that generates Drop(arr.Subslice(1,3,false)) in the MIR — the exact pattern described in the Codex review comment.
_projected_ty() returned the original array type for Subslice projections, so call_edges missed drop glue for subslice drops like Drop(local.Subslice(1,3,false)) and reduce_to() pruned the required drop_in_place::<[T; M]> function. Compute the result array length from the Subslice parameters (to - from for from_end=false, len - from - to for from_end=true) and search the type table for a matching ArrayType with the same element type and length.
89291c4 to
7fb84c9
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7fb84c93e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Summary
interior-mut-fail.rsshould pass under rustc, but KMIR failed on the secondRefCell::borrow_mut()by reachingpanic_already_borrowed(noBody).The root cause was not
RefCellwriteback. It was that KMIR still treated MIRDropterminators as no-ops, and the pre-proof SMIR reduction also discardeddrop_in_place::<...>bodies becauseDropwas not modeled as a reachability edge.This PR fixes that by:
Drop-based edges tocall_edgesDropterminators through the normal call path using reachabledrop_in_place::<T>bodiesAfter that, the temporary
RefMutguard from the firstborrow_mut()is actually dropped, the borrow flag is released, andinterior-mutpasses.Additional fixes
While validating the initial change, this PR also fixed two follow-up issues that the new drop-glue path exposed:
Downcast + Fieldprojections, so enum variant fields keep the correctdrop_in_place::<FieldTy>edgeNoOpSymdrop-glue shims as real no-op calls, instead of letting them fall through as unknown or ordinary body-less callsIt also adds minimal bridge rules for the newly exposed
PointerOffset + Field + Unionprojection path so the updated drop-glue execution can complete without getting stuck.Follow-up
Issue #1011 tracks the follow-up refactor to unify
#traverseProjection's representation invariant and remove the temporary bridge rules introduced here.