Skip to content

Laurel: field-granular modifies frame#1404

Open
julesmt wants to merge 8 commits into
reviewed-kbd-will-merge-to-mainfrom
julesmt/feature/field-granular-modifies
Open

Laurel: field-granular modifies frame#1404
julesmt wants to merge 8 commits into
reviewed-kbd-will-merge-to-mainfrom
julesmt/feature/field-granular-modifies

Conversation

@julesmt

@julesmt julesmt commented Jun 23, 2026

Copy link
Copy Markdown
Member

Makes modifies o#f frame only the (o, f) pair instead of the whole owner object: that field may change while all other fields and every other object stay fixed.

#1402

julesmt added 3 commits June 23, 2026 13:14
`modifies o#f` now frames only the (o, f) pair, so that field may change
while all other fields and objects stay fixed. Before, it framed the
whole owner object.

- ModifiesEntry gains a `.field objExpr fieldConst` case.
- matchModifiesFieldRead matches a lowered `readField($heap, o, f)`.
- buildNotModifiedForEntry emits `!($obj == o && $fld == f)`.
Parse modifies refs at precedence 0 so `modifies o#f` works without
parentheses, like whole-object targets.
Tests for the field-granular frame, each checking the modified field can
change while other fields and objects stay fixed: caller/callee
enforcement, cross-type calls, opaque stubs, multiple and mixed targets,
and inherited fields.

@keyboardDrummer keyboardDrummer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add more documentation to the modifies field in LaurelAST, explicitly stating the allowed modes:

  • single object
  • object set
  • field of single object

I think we could also support a "field of object set", but given that Laurel doesn't have sets yet it seems hard to test that.

Comment thread Strata/Languages/Laurel/ModifiesClauses.lean Outdated
Comment thread Strata/Languages/Laurel/ModifiesClauses.lean Outdated
Comment thread Strata/Languages/Laurel/ModifiesClauses.lean Outdated

@fabiomadge fabiomadge left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for soundness; built at 3e52bce1d (suite green). The field-granular frame is sound: it's a frame tightening (.field adds !($obj==o && $fld==f) to notModified, preserving strictly more), the gate is safe since fieldConst is the per-type DeclaringType.fieldName constant (a#x can't free b#x), and aliasing holds — T9_ChainedFieldAccess's chainedMayAliasFails confirms a write through a possible alias isn't framed away. Frame violations caught, valid writes pass.

Non-blocking, reinforcing @keyboardDrummer's suggestion to stop HeapParameterization translating field reads in modifies clauses: matchModifiesFieldRead matches by callee text ("readField", startsWith "Box"), coupling to HeapParameterization's names and single-Box wrapping depth. If that pass changes, an o#f target silently falls through with no diagnostic. That suggestion (or the structured ModifiesTarget it proposes) removes this; short of that, share those names as constants.

julesmt added 4 commits June 24, 2026 12:05
List the allowed modifies forms on Body.Opaque: single object, object set, field of an object (o#f), and the wildcard.
Factor the repeated diagnostic construction in filterBodyNonCompositeModifies into a single helper.
Keep o#f modifies targets symbolic through heap parameterization and match them directly, removing the readField/Box string matching.
Validate modifies entries during resolution and remove the separate filter pass.
@julesmt

julesmt commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

@keyboardDrummer @fabiomadge updated with your suggestions; one commit per suggestion

@keyboardDrummer

Copy link
Copy Markdown
Contributor

Beautiful! Thanks so much

fabiomadge
fabiomadge previously approved these changes Jun 25, 2026
@julesmt
julesmt dismissed stale reviews from fabiomadge and keyboardDrummer via dbc48c6 June 25, 2026 17:11
@julesmt
julesmt requested a review from keyboardDrummer June 25, 2026 17:12
@julesmt
julesmt requested a review from fabiomadge June 25, 2026 17:12
fabiomadge
fabiomadge previously approved these changes Jun 25, 2026
The merge of reviewed-kbd-will-merge-to-main into the field-granular
modifies branch left two bad conflict resolutions that broke the build:

- Dropped the stale 2-arg `buildNotModifiedForEntry obj` call (type
  mismatch); kept the field-granular 3-arg `(obj, fld, entry)` version.
- Removed `filterNonCompositeModifiesPass`, which referenced the deleted
  `filterNonCompositeModifies` (the non-composite check now lives in
  `Resolution.resolveModifiesEntry`).

Verified `lake build Strata.Languages.Laurel.ModifiesClauses` and the
full Laurel pipeline compile.
@julesmt
julesmt force-pushed the julesmt/feature/field-granular-modifies branch from dbc48c6 to 49c518d Compare June 25, 2026 17:54
@keyboardDrummer
keyboardDrummer added this pull request to the merge queue Jun 26, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to Branch Protection failures Jun 26, 2026
You're not authorized to push to this branch. Visit "About protected branches" for more information.
@julesmt
julesmt enabled auto-merge June 26, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants