Skip to content

Improve error messages: unimported module qualifiers and nominal-vs-record mismatches - #10290

Draft
jaredramirez wants to merge 4 commits into
mainfrom
jared/unimported-module-and-nominal-hints
Draft

Improve error messages: unimported module qualifiers and nominal-vs-record mismatches#10290
jaredramirez wants to merge 4 commits into
mainfrom
jared/unimported-module-and-nominal-hints

Conversation

@jaredramirez

@jaredramirez jaredramirez commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Two error-reporting improvements, one commit each.

1. Clearer error when a qualified ident's module or type cannot be found

Previously, using Stdin.line!() without import pf.Stdin reported only:

┌────────────────┐
│ DOES NOT EXIST ├─ Stdin.line! does not exist.

which reads as "this function doesn't exist" when the real problem may be a missing import. When a qualified ident fails to resolve because its leading qualifier is neither an imported module nor a type in scope, canonicalization now keeps the existing qualified_ident_does_not_exist diagnostic and DOES NOT EXIST title while adding clearer context to the body:

┌────────────────┐
│ DOES NOT EXIST ├─ `Stdin.line!` does not exist.

    The name `Stdin` is not an imported module or a type in scope.

    If `Stdin` is a module, you may need to import it at the top of the file.
    For example:

        import pf.Stdin

The suggested import uses the file header's platform shorthand (or first package shorthand) when one exists, and falls back to a bare import Stdin otherwise. The diagnostic carries explicit lookup context: the missing-module-or-type path records the unresolved name and complete suggested import, while the existing missing-exposed-value path has its own context and retains the shorter report body. This avoids a duplicate unresolved-qualified-identifier diagnostic tag while keeping the renderer's behavior explicit.

2. Field-level hints for nominal-vs-record type mismatches

A record that mismatches a nominal annotation like

ToolDefinition(input) := { name : Str, description : Str, call : input -> Str }

previously showed only the two types with no hint. The snapshot type diff now opens a nominal type on exactly one side of a structure-vs-structure comparison and compares its declaration backing, so the usual record hints apply:

    Hint: This record is missing the field: `call`

This is gated on the backing being visible from the module reporting the error — the nominal type is transparent, or it was declared in that module — mirroring types.NominalType.canLiftInner (the same rule as whether a nominal type can be opened). SnapshotNominalType now carries is_opaque to make that check possible at report time.

Testing

  • New snapshot tests: test/snapshots/can_import_missing_import_suggestion.md, test/snapshots/nominal/nominal_record_mismatch_field_hint.md; existing snapshots regenerated.
  • zig build run-test-zig-module-can passes, and all affected snapshots pass --check-expected --check-output validation.
  • The earlier full run-test-zig run passed (3432 passed / 0 failures). The json_decoder / http_header_decoder platform steps fail with an ARC-certifier panic, which I verified is byte-identical on a clean checkout of main (pre-existing, unrelated).

🤖 Generated with Claude Code

https://claude.ai/code/session_01DGo1pdehucvHBTSoGBm22n

@jaredramirez jaredramirez self-assigned this Jul 20, 2026
@jaredramirez
jaredramirez force-pushed the jared/unimported-module-and-nominal-hints branch 10 times, most recently from 55e30af to af74c35 Compare July 24, 2026 19:18
@jaredramirez
jaredramirez force-pushed the jared/unimported-module-and-nominal-hints branch from af74c35 to b738d44 Compare July 25, 2026 15:09
@jaredramirez
jaredramirez marked this pull request as ready for review July 25, 2026 16:41
@jaredramirez
jaredramirez marked this pull request as draft July 25, 2026 16:42
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