Implement Typed IR#504
Conversation
This will be replaced with `Symbol.erasedType`.
`Call`, `Lambda`, `Select`, and `DynSelect` is left for a future commit.
LPTK
left a comment
There was a problem hiding this comment.
Some possible next immediate steps:
- Update printer to show the erased types at variable and member declaration/definition sites.
- Update
Loweringso it generates erased types from parameter type annotations, to be used to annotate the correspondingVarSymbol. - Make sure we are never overriding an existing erased type in a given symbol by using
softAssert, as a sanity check.
A subtlety we should get right: the erasure of annotated class parameter types should successfully propagate to their defining fields. Param has a ``fldSym` which can be used for this.
| new Rewriter(instId).applyBlock(ogBody), | ||
| mkReturnCall(restFunSym, restFunArgs)) | ||
| val refreshedFvSymbols = dtorBranchFnFvs(branchId._1).map(s => s -> new VarSymbol(Tree.Ident(s"fv_${s.nme}"))) | ||
| val refreshedFvSymbols = dtorBranchFnFvs(branchId._1).map(s => s -> new VarSymbol(Tree.Ident(s"fv_${s.nme}"), erasedType = N)) |
There was a problem hiding this comment.
It seems many cases like this one should carry over the previous erasedType somehow.
|
The current task list (work items created by me, organized by AI):
|
What does that mean?
This should be moved to phase B. In fact, it's the first thing yoiu should do, just so you can actually see what you're doing! |
Good point, I have updated to task list. |
Refinement of types during Lowering is implemented later.
When a variable is assigned twice using different-typed values.
|
A summary of the current state of this branch (since I will work on NAC3 next week):
Follow-ups:
There is also a bigger issue that needs to be fixed: When narrowing the type of parameters/results in the WAT, Binaryen rejects the code with the error:
This issue needs to be fixed separately, so I suspect by the time I pick this back up I will work on this issue first. |
For now, all we need is for selections like
IMO nontrivial inference (ie other than just propagating information inside out) isn't an objective of this PR. When the new frontend is in place, the resolution process will already do this sort of type inference for us, so there should be nothing to do at the IR level. I don't really understand the binaryen problem. You need to investigate it more and really understand the cause. Claude hallucinates about these things half of the time (if not more). Before moving on, can you please open separate micro-PRs to merge what can be merged separately (eg the NoSymbol object) so this PR doesn't get out of sync too badly? |
Done, opened as #516. There doesn't seem to be other things that can be merged separately for now. |
|
Could you pls notify me when this is ready? I feel like we should try to make the lifter type-preserving. I can do it in a separate PR. BTW, tail recursion optimization for mutually recursive functions will break the typedness of the IR. When we have mutually recursive tailrec functions, we merge them into one giant function with a switch whose parameter list is a union of the other parameter lists, rather than a concatenation of them, so each parameter could have a different type depending on what function we are entering. |
After some really deep sessions and several MREs, here is the root cause of the issue: As expected, Binaryen's Example: (type $Object (sub (struct)))
(type $O (sub $Object (struct (field $i i32))))
(type $O_ctor (func (result (ref $O))))
(type $entry (func (result (ref null any))))
One solution is to use (type $Object (sub (struct)))
(rec
(type $O (sub $Object (struct (field $i i32))))
(type $O_ctor (func (result (ref $O)))))
(type $entry (func (result (ref null any)))) ;; (rec (type $entry ...))However, this would introduce a more subtle issue - If two classes have exactly the same type on everything, except one field, method parameter, or result type just so happens to be uninferrable in the IR and is coerced down into I can only think of two ways moving forward.
Let me know what you think about this. Edit: The MREs can be found here |
|
Thanks for looking into this!
Yes, can we just fork Binaryen, fix this, and open a PR? In the meantime, we just use our own fork. Can be done either with a Git submodule or by publishing our own npm package for the fork (or some other solution, whichever you prefer). |
Done in #536, although not as a submodule - I instead forked the Binaryen repo, patched it to add |
|
Please fix the conflicts of this branch, and let's try to merge it soon, isntead of letting it diverge again over weeks. |
No description provided.