check: support web bundle idioms so full type-check passes#81
Merged
Conversation
Running `loon check` on the concatenated web bundle failed with 1000+
errors (starting with E0205 no `Eq` for `Vec`), so `npm run build:full`
exited non-zero and pre-rendering-from-source was blocked. The
interpreter handled all of this fine — these were checker gaps, not
web/src bugs. Fixes, all in the checker:
- Register builtin `Eq` (and it already had) impls for Vec/Map/Set,
which compare structurally at runtime.
- Variadic `& rest` params: split params at `&`, bind rest as `Vec elem`,
and collect extra call-site args into the rest Vec.
- Undeclared type names in ADT field positions act as implicit type
params (e.g. `Props` in `[El String Props ...]`) instead of becoming
rigid nominal types.
- `get`: 3-arg `[get coll key default]` no longer forces field presence;
dynamic (non-literal) keys on records return unconstrained.
- Union-friendly `if`/vector literals: heterogeneous branches/elements
back off to an unconstrained type; `if` no longer ties two unknown
branch types together. `[if true 1 2]` still infers Int.
- Empty `{}` stays polymorphic (used as empty props everywhere).
- Loosen `len`/`contains?`/`nth` to match runtime polymorphism
(strings, tuples, maps).
- Pre-declare top-level `fn` names so forward/mutual references resolve;
genuine typos still error.
`npx tsx web/build.ts` (full, with type-check) now completes; all
workspace tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
What shippedThis is a purely internal change with no user-visible effect. The type-checker used by the build toolchain has been updated to handle patterns common in the web codebase, so the full build process now completes successfully without errors. Plain-English summary generated by Choji from this pull request. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Running
loon checkon the concatenated web bundle (built byweb/build.tsintoweb/dist/bundle.loon) failed with 1000+ errors — starting with[E0205] no Eq implementation for type Vec. This madenpm run build:full(the Rust-enabled build with type-checking, step 6 ofweb/build.ts) exit non-zero, blocking pre-rendering-from-source. The Vercel deploy only worked because it uses the--no-rustpath that skips type-checking entirely.The interpreter runs all of this code fine — every error was a type-checker gap, not a bug in
web/src. So this PR fixes the checker (noweb/srcchanges).Changes (all in
crates/loon-lang/src/check/mod.rs)Eq(the original E0205): registered builtinEqimpls for containers, which compare structurally at runtime.& restparams (~1,040 arity errors): split params at&, bind the rest param asVec elem, and at call sites to known variadic fns collect extra args into the rest Vec (rest elements stay unconstrained — HTML children are heterogeneous).Propsin[El String Props [Vec VNode]]was becoming a rigid nominal type nothing could unify with.get: 3-arg[get coll key default]no longer forces field presence; dynamic (non-literal) keys on records return an unconstrained type.if/vector literals: branches/elements with distinct concrete types back off to an unconstrained type instead of erroring, andifno longer ties two still-unknown branch types together (which wrongly equated unrelated params in[if [map? x] x y]dispatch code).[if true 1 2]still infersInt.{}stays polymorphic instead of forcingMap t t(used as empty props throughout).len,contains?, andnthto match runtime polymorphism (strings, tuples, maps).check_programpre-declares top-levelfnnames with a∀a. aplaceholder so mutual recursion across definitions (coerce-child↔coerce-children) and cross-file use-before-def resolve; the real scheme replaces the placeholder at the definition site. Genuine typos still error.Trade-off for reviewers
Several of these are deliberate gradual-typing back-offs: heterogeneous unions and forward-referenced calls become unchecked rather than errors. This matches the "invisible types" philosophy and was the only way to type the
ui.loonruntime-dispatch style ([if [map? first] ...]) without occurrence typing.Verification
npx tsx web/build.ts(full, with type-check) → exit 0, warnings only.cargo test --workspace→ all pass (700+, zero failures).🤖 Generated with Claude Code