fix(types): check nested closure/function bodies and cast targets (issue 0064)
Closes the two residual silent holes in the unknown-type diagnostic: - Nested closure / function bodies. The body walk stopped at closure and nested-fn boundaries, so a typo'd type in a closure's local annotation silently became a 0-field struct. `walkBodyTypes` now descends control flow and expressions to re-enter each closure / nested fn via `checkScope`, which accumulates that scope's generic + value-`Type` params onto the parent's — so an inner closure still sees the outer function's `$T` (no false positive) while a genuine unknown is flagged at any nesting depth. `harvestScopeDecls` collects type-decl names across the whole body (including nested scopes) up front so locals are never false-flagged. - Cast targets. `cast(T)` where `T` is a value-`Type` param (no `$`) cast to a fabricated empty struct silently; it now gets the tailored `$T` hint. An unknown *literal* cast target already errors via value resolution, so it's left to that path — no double diagnostic. Suite: 350 passed, 0 failed. Regressions: examples/1114 (nested-closure annotation), 1115 (cast value param).
This commit is contained in:
@@ -26,10 +26,19 @@
|
||||
> ran with the value dropped. Nested function / closure bodies are their own scope
|
||||
> and are not descended (safe under-coverage); explicit `cast(T)` already has its
|
||||
> own `unresolved` diagnostic and is left to it.
|
||||
> Regression tests: `examples/1111-diagnostics-nondollar-type-param-rejected.sx`
|
||||
> (tailored hint), `examples/1112-diagnostics-unknown-type-name-rejected.sx`
|
||||
> (typo'd field type), and `examples/1113-diagnostics-unknown-type-local-var-rejected.sx`
|
||||
> (body-level local annotation) — all exit 1. Suite: 348 passed, 0 failed.
|
||||
> The walk descends into **nested closure / function bodies** too (`walkBodyTypes`
|
||||
> + `checkScope`): each scope accumulates its generic params onto the parent's, so
|
||||
> a closure body still sees the enclosing function's `$T`, and a type annotation in
|
||||
> any nesting depth is checked. `harvestScopeDecls` collects type-decl names across
|
||||
> the whole body (including nested scopes) so locals aren't false-flagged. Cast
|
||||
> targets are handled too: `cast(T)` where `T` is a value-`Type` param (the
|
||||
> otherwise-silent cast case) gets the tailored hint, while an unknown *literal*
|
||||
> cast target is left to the existing value-resolution `unresolved` diagnostic (no
|
||||
> double-report). The only remaining under-coverage is benign (annotations buried in
|
||||
> AST positions the walker doesn't descend stay unchecked — never a false positive).
|
||||
> Regression tests: `examples/1111` (tailored hint, signature), `1112` (typo'd field
|
||||
> type), `1113` (body-level local annotation), `1114` (nested-closure annotation),
|
||||
> `1115` (`cast` value param) — all exit 1. Suite: 350 passed, 0 failed.
|
||||
|
||||
## Symptom
|
||||
|
||||
|
||||
Reference in New Issue
Block a user