Skip to content

Codegen passing#13

Open
roryc89 wants to merge 135 commits intomainfrom
codegen-passing
Open

Codegen passing#13
roryc89 wants to merge 135 commits intomainfrom
codegen-passing

Conversation

@roryc89
Copy link
Member

@roryc89 roryc89 commented Mar 17, 2026

No description provided.

roryc89 and others added 30 commits March 18, 2026 20:50
… JS names

When an unnamed instance's generated JS name (e.g., namedExportStillWorksUnit
from class NamedExportStillWorks + type Unit) collides with a value declaration
in the same module, the instance dict variable and the value function get the
same name, causing runtime errors ("a is not a function").

This adds name deduplication for generated instance/derive instance names:
- Pre-populates used_js_names with all value, constructor, foreign, and class
  member names before generating declarations
- When generating an unnamed instance name, checks for collisions and appends
  numeric suffixes (e.g., namedExportStillWorksUnit1)
- Records the deduplication mapping so dict_expr_to_js uses the correct
  deduplicated name when resolving instance references

Also removes InstanceNamesGenerated from known_node_failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When an operator (like `/`) appears inside a generalized local let binding,
the typeclass constraint may not resolve to a concrete dictionary because the
type variable was generalized away. This adds try_inline_bare_op to detect
bare ModuleAccessor references to known class methods (div, add, sub, mul,
eq, etc.) and emit native JS binary operations instead of dictionary-applied
calls. Fixes the OperatorSections fixture's `Data_EuclideanRing.div(...) is
not a function` runtime error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three fixes for higher-rank type dictionary passing:

1. Typechecker constraint inference (check.rs): When inferring constraints
   for a binding, only count Type::Var args as overlapping if they appear
   in the function's own type. Previously, all Type::Var args were treated
   as overlapping, causing inner-forall constraints (e.g. Monad m from a
   data constructor field) to incorrectly propagate to the outer function.

2. Return-type forall instantiation (infer.rs): Map alpha-renamed forall
   variable names back to their base names when substituting constraint
   args. The return_type_constraints stores original names (e.g. `m`) but
   the Type::Forall vars may have been alpha-renamed to `m$5688`.

3. Codegen dict application (js.rs): Skip return-type constraint dicts
   when applying resolved dicts at a Var reference site. These dicts
   should only be consumed by the RT_DICT mechanism in the App handler
   after enough regular args have been applied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add kind-aware instance matching so that instances distinguished only by
kind annotations (e.g. ShowP (Proxy (a :: Type)) vs ShowP (Proxy (a :: Symbol)))
dispatch to the correct instance at runtime. Previously both resolved to
the first match because convert_type_expr strips kind annotations.

Introduces instance_var_kinds side table to preserve kind info per instance,
and checks bound type compatibility during dictionary resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nstances for dict resolution

Anonymous `derive instance` declarations (without explicit names) were not
being registered in `instance_registry_entries` in the typechecker, causing
`resolved_dicts` to miss Functor dictionary lookups for types like Test1/Test3.
Also extended codegen to handle unnamed derive instances in CST scanning,
added Bifunctor/Profunctor derive support, and resolved rmap fallback logic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multi-parameter type classes like `IsStream el s | s -> el` had their
instance registry entries missing because `extract_head_type_con` only
looked at the first type argument. When the first arg is a type variable
(e.g., `a` in `IsStream a (Stream a)`), no head was extracted and the
instance was never registered. Similarly, `resolve_dict_expr_from_registry`
only tried the first concrete arg for registry lookup.

Fix by trying all type arguments when the first doesn't yield a result
(for registry building) or doesn't match a registry entry (for lookup).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…derive instances for dict resolution"

This reverts commit 1b7655d.
Extract head type constructor from all type arguments, not just the first.
Multi-parameter type classes may have type variables in early positions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rewrite body_has_tail_call to detect mutual recursion by collecting
  local function definitions that tail-call the outer function, then
  checking if return statements call any local function in the chain
- Add expr_root_callee helper to extract root callee from curried apps
- Update local_fn_has_tail_call_to to look inside $tco_loop for
  already-TCO'd inner functions (needed for tco3's nested TCO)
- Fix loopify_tco_structure: don't set $tco_done after inner while loop,
  since the inner $tco_loop already handles this for base cases
- Add reorder_let_bindings_by_deps for dependency-based topological sort
  of let bindings (fixes ntco4 where g=h(x) preceded h's definition)
- Remove TCOMutRec from known_node_failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts 14 commits (fixture fix attempts and merges) to return
to the clean state at 8646b01.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…build_fixture_original_compiler_failing, build_from_sources)
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