Skip to content

Resolve named struct fields in formula translation#118

Merged
coord-e merged 2 commits into
mainfrom
claude/named-field-formula-fn
Jun 12, 2026
Merged

Resolve named struct fields in formula translation#118
coord-e merged 2 commits into
mainfrom
claude/named-field-formula-fn

Conversation

@coord-e

@coord-e coord-e commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Summary

The formula translator (AnnotFnTranslator, used by requires/ensures/invariant/predicates) handled ExprKind::Field only for numeric tuple field names (.0, .1). Structs are represented as tuples in the logic, so accessing a named field — e.g. result.x in an ensures formula — panicked with tuple field index must be a non-negative integer.

This resolves a named field to its position in the ADT's (single, non-enum) variant, producing the same tuple-projection term as the numeric path. Numeric tuple indices keep their fast path.

#[ensures(result.x == p.y && result.y == p.x)]   // now works
fn swap(p: P) -> P { P { x: p.y, y: p.x } }

Change

  • src/analyze/annot_fn.rsExprKind::Field: when the field name isn't a numeric index, look up the field position via expr_ty().ty_adt_def()'s non-enum variant.

Tests

  • tests/ui/{pass,fail}/formula_struct_field.rs — an ensures formula referring to struct fields by name (pass = correct postcondition for swap; fail = postcondition violated).

Context

Extracted from the thrust::predicate Rust-syntax work (PR #114) as an independent, self-contained improvement to the formula translator. PR #114's trait/struct predicate tests depend on this.

https://claude.ai/code/session_01WdLyxyy4ieAxrexj83X5MX


Generated by Claude Code

The formula translator's `ExprKind::Field` handler only accepted numeric
tuple field names (e.g. `.0`). Structs are represented as tuples in the
logic, so named field access like `result.x` panicked. Resolve a named
field to its position in the ADT's variant, matching the tuple-projection
form, so specifications can refer to struct fields by name.

https://claude.ai/code/session_01WdLyxyy4ieAxrexj83X5MX
coord-e pushed a commit that referenced this pull request Jun 11, 2026
Replace the synthetic `Clause` used to render a predicate's translated
formula with a `TermSortEnv` trait: anything that can resolve a term-level
variable's sort (a `Clause` via its `vars`, or a bare `IndexVec<TermVarIdx,
Sort>` for a define-fun signature) can drive term rendering. The smtlib2
Display wrappers now hold `&dyn TermSortEnv` instead of `&Clause`, so no
fake clause is fabricated.

Also revert the named-struct-field translator change and the trait
predicate test conversions: that field resolution is now a separate PR
(#118). The trait predicate tests stay on raw SMT2 here and can move to
Rust syntax once the field PR lands; the scalar free-function predicate
test exercises the Rust-syntax path.

https://claude.ai/code/session_01WdLyxyy4ieAxrexj83X5MX
@coord-e coord-e marked this pull request as ready for review June 12, 2026 15:55
@coord-e coord-e requested a review from Copilot June 12, 2026 15:55

Copilot AI 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.

Pull request overview

This pull request fixes AnnotFnTranslator’s formula translation of ExprKind::Field so that named struct field accesses (e.g. result.x) are resolved to their positional tuple-projection index in the logical encoding, instead of panicking when the field name is not a numeric tuple index.

Changes:

  • Extend ExprKind::Field translation to map named ADT fields to their index in the struct’s (non-enum) variant field list.
  • Preserve the existing fast path for numeric tuple field names (.0, .1, …).
  • Add UI pass/fail tests covering ensures formulas that reference struct fields by name.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/analyze/annot_fn.rs Resolve named struct fields to tuple-projection indices during formula translation.
tests/ui/pass/formula_struct_field.rs Adds a passing UI test verifying ensures can reference struct fields by name.
tests/ui/fail/formula_struct_field.rs Adds a failing UI test where the named-field postcondition is intentionally incorrect (Unsat).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coord-e coord-e merged commit 1d85b18 into main Jun 12, 2026
7 checks passed
@coord-e coord-e deleted the claude/named-field-formula-fn branch June 12, 2026 16:01
coord-e pushed a commit that referenced this pull request Jun 12, 2026
Now that named struct-field resolution is on main (#118), flip the trait
predicate tests (annot_preds_trait, annot_preds_trait_multi; pass and fail)
from raw SMT-LIB2 bodies to Rust-expression bodies using `self.x`.

https://claude.ai/code/session_01WdLyxyy4ieAxrexj83X5MX
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.

3 participants