Skip to content

[Repo Assist] feat: add GenerateAnonRecordStub code fix for FS3578 (closes #455)#1510

Draft
github-actions[bot] wants to merge 3 commits intomainfrom
repo-assist/fix-455-anon-record-stub-b8de6b693d4abf96
Draft

[Repo Assist] feat: add GenerateAnonRecordStub code fix for FS3578 (closes #455)#1510
github-actions[bot] wants to merge 3 commits intomainfrom
repo-assist/fix-455-anon-record-stub-b8de6b693d4abf96

Conversation

@github-actions
Copy link
Contributor

🤖 This is an automated pull request from Repo Assist.

Closes #455.

What

Adds a new GenerateAnonRecordStub code fix triggered by FS3578 ("Two anonymous record types have mismatched sets of field names").

When you write an anonymous record literal that is missing fields required by its expected type, the fix inserts stub bindings fieldName = failwith "Not Implemented" for each absent field before the closing |}.

Before:

let f (x: {| A: int; B: string |}) = x
let y = f {| A = 1 |}   // FS3578

After applying the fix:

let f (x: {| A: int; B: string |}) = x
let y = f {| A = 1; B = failwith "Not Implemented" |}
```

The fix also handles:
- Adding multiple missing fields at once
- Adding fields to an empty anonymous record (`{||}` → `{| A = failwith "..." |}`)
- Cases where both field sets differ (takes the union of missing fields)

## How

- **`GenerateAnonRecordStub.fs/.fsi`**new `CodeFix` module using `Run.ifDiagnosticByCode ["3578"]`. Parses the two field-name sets from the error message with a regex, finds the innermost `SynExpr.AnonRecd` containing the cursor position via `ParsedInput.tryPick`, computes missing fields, and inserts the stubs before `|}` (at `range.EndColumn - 2`).
- **`AdaptiveServerState.fs`**  registers the new fix in the server's code-fix array.
- **`GenerateAnonRecordStubTests.fs`**  three test cases: one missing field, multiple missing fields, and an empty anonymous record.

## Test Status

```
dotnet build src/FsAutoComplete/FsAutoComplete.fsproj -f net8.0   Build succeeded (0 warnings, 0 errors)
dotnet build test/FsAutoComplete.Tests.Lsp/FsAutoComplete.Tests.Lsp.fsproj -f net8.0  Build succeeded (0 warnings, 0 errors)
dotnet fantomas (new files)  1 file formatted, 2 unchanged

Full test suite was not run (requires a live FSAC server and several minutes). The new test cases follow the same pattern as IntroduceMissingBindingTests and GenerateRecordStub tests.

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@d1d884596e62351dd652ae78465885dd32f0dd7d

When an anonymous record literal is missing fields required by its
expected type, offer a code action that inserts stub bindings
`fieldName = failwith "Not Implemented"` for each missing field before
the closing `|}`.

The fix is triggered by FS3578 ('Two anonymous record types have
mismatched sets of field names'). It parses the two field-name lists
from the diagnostic message, finds the anonymous record expression in
the parse tree, and computes which fields are absent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Krzysztof-Cieslak
Copy link
Member

/repo-assist CI is failing

@github-actions
Copy link
Contributor Author

github-actions bot commented Mar 19, 2026

Repo Assist completed successfully!

…r message formats

The code fix was using diagnostic code 3578 with an old message format
('Two anonymous record types have mismatched sets of field names ["A"; "B"] and ["A"]')
that the current F# compiler no longer produces.

Current F# compiler (>= 8) emits FS0001 for anonymous record field mismatches
with these message formats:
- "This anonymous record is missing field 'B'."
- "This anonymous record is missing fields 'B', 'C'."
- "This anonymous record does not exactly match the expected shape.
    Add the missing fields [B; C] and remove the extra fields [D; E]."

Updated the code fix to:
1. Trigger on FS0001 with a message guard for 'anonymous record' + 'missing'
2. Parse missing field names from the three new message formats
3. Preserve the existing AST-based insertion logic

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor Author

Commit pushed: c031479

Generated by Repo Assist

@github-actions
Copy link
Contributor Author

🤖 Repo Assist here — I've pushed a fix for the CI failures.

Root cause: The code fix was triggering on diagnostic code "3578" with an old FS3578 message format ('["A"; "B"]' and '["A"]'), but the current F# compiler (≥ 8) no longer emits FS3578 for anonymous record field mismatches. It instead emits FS0001 with different message formats:

Scenario Actual message
Single missing field This anonymous record is missing field 'B'.
Multiple missing fields This anonymous record is missing fields 'B', 'C'.
Wrong fields (add + remove) This anonymous record does not exactly match the expected shape. Add the missing fields [B; C] and remove the extra fields [D; E].

Fix applied:

  • Changed trigger from "3578""1" (FS0001), guarded by a message filter ("anonymous record" && "missing")
  • Rewrote the field-name extraction (tryParseMissingFields) to handle all three current message formats
  • The AST-based insertion logic is unchanged

The code fix should now correctly trigger and insert the missing field stubs.

Generated by Repo Assist for issue #1510 ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@d1d884596e62351dd652ae78465885dd32f0dd7d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The record generator for anonymous records.

1 participant