Skip to content

feat[next]: friendly errors for invalid field-operator and program bodies#2663

Draft
havogt wants to merge 7 commits into
GridTools:mainfrom
havogt:next_friendly_errors_compile
Draft

feat[next]: friendly errors for invalid field-operator and program bodies#2663
havogt wants to merge 7 commits into
GridTools:mainfrom
havogt:next_friendly_errors_compile

Conversation

@havogt

@havogt havogt commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Compile-time half of the round-2 DSL error hardening. Split out of #2661 (follow-up to #2655).

Turns crashes into actionable DSLErrors while parsing and type-checking '@field_operator' and '@program' bodies:

  • global / nonlocal statements (previously crashed SingleAssignTargetPass with an AttributeError)
  • invalid attribute access in field operators, with "Did you mean ...?" suggestions
  • invalid subscripts and dimension indices
  • unresolvable or invalid type annotations
  • invalid statements and calls in programs
  • comparison-chain error reformatted into message + hint

Companion PRs:

  • eve infer_type fix: independent (see the eve split PR)
  • call-time / construction / builtins: stacked on this one (see the runtime split PR)

havogt added 7 commits June 16, 2026 19:59
'global x' inside a field operator crashed SingleAssignTargetPass with
AttributeError ('str' object has no attribute '_fields') because the
pass visited the plain-string 'names' field of the statement. Skip
non-AST field values in NodeYielder.generic_visit so the statement
reaches the dialect parser, and register friendly names + hints for
'global'/'nonlocal' there.
Attribute accesses like 'a.T', 'a.transpose()' or 'np.sin(a)' leaked
raw AttributeError/ValueError from FOAST type deduction. Guard
visit_Attribute: report nonexistent attributes (with a NumPy-specific
note for fields/scalars and 'did you mean' for named collections),
nonexistent namespace members, and namespace members whose value has no
DSL type (with a hint towards GT4Py built-ins). Also publish the
did_you_mean helper for reuse.
Three crashes in FOAST type deduction become diagnostics:
- 'field[3]' leaked AttributeError ('ScalarType' has no 'dim'); now
  explains that absolute indexing is unavailable and points to field
  offsets / local-dimension indices.
- 'tuple[5]' on a 2-tuple leaked IndexError; now reports the index and
  the tuple size.
- 'IDim(3)' on a non-local dimension crashed an assert; now explains
  that only local-dimension indices can be constructed.
Three annotation failure modes leaked raw Python exceptions:
- annotations that typing.get_type_hints cannot resolve (invalid
  forward-reference strings, undefined names) raised SyntaxError or
  NameError; now wrapped into a DSLError pointing at the function.
- parameter annotations that have no GT4Py type (e.g. 'a: list',
  'inp: gtx.Field' without arguments) raised ValueError from type
  translation; now InvalidParameterAnnotationError, with the underlying
  reason as a note and a hint showing valid annotations.
- annotated assignments inside an operator ('b: gtx.Field[...] = a')
  raised NameError when the annotation used names not visible inside
  the function; now a DSLError explaining what names are available.
Three program-level crashes become diagnostics:
- a bare expression statement ('a + a') leaked a TypeError from IR node
  validation; now explains that program statements must be operator
  calls.
- calling a '@program' from another program crashed with an
  AssertionError; now a DSLError suggesting to call the field operators
  directly or compose programs in Python.
- referencing a plain (undecorated) Python function leaked a ValueError
  from type translation; now a DSLTypeError hinting at
  '@field_operator'/'@scan_operator'. Other non-translatable closure
  variables in programs get the same wrapping as in field operators.
DSLTypeError now forwards the structured diagnostic payload
(label/notes/hints) to DSLError.
The message started with a newline and embedded a multi-line code block,
which rendered awkwardly; the replacement suggestion is now a hint in
the structured diagnostics format.
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