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.
| /** Refines the erased type if it was not previously refined, but allowing for idempotent refinements to the same | ||
| * type. | ||
| * | ||
| * A soft assert will be raised if the erased type was already refined to a different type. |
There was a problem hiding this comment.
This comment is AI, right? Please clean up to remove dumb comments that just restate the code.
There was a problem hiding this comment.
Nope, that's me. Part of my "style" of writing comments is to document any invariants and side effects of a function with the assumption that nobody will bother to read the function implementation (think hovering over a function call to read the documentation).
I tried to make the docstring a bit more concise in dd94b46.
There was a problem hiding this comment.
Ok. By the way, why do you call this "refine"? It does not refine anything, it just inserts the relevant information where it used not to be.
|
|
||
| // * Used, eg, as the Assign receiver of intermediate computations whose result is not used | ||
| final class NoSymbol(using State) extends MaybeSymbol: | ||
| final class NoSymbol extends MaybeSymbol: |
There was a problem hiding this comment.
It just occurred to me that this can just be an object.
| //│ return id¹(tmp) | ||
| //│ ——————————————| Optimized IR |—————————————————————————————————————————————————————————————————————— | ||
| //│ let id⁰; define id⁰ as fun id¹(a: ?) { return a }; return new Foo⁵(1) | ||
| //│ let id⁰: ?; define id⁰ as fun id¹(a: ?) { return a }; return new Foo⁵(1) |
There was a problem hiding this comment.
There should probably also be a return type info on id¹.
| doc"let ${names.mkString(", ")}; # ${print(body)}" | ||
| case s: TempSymbol => doc"${scope.allocateName(s)}${erasedTypeAnnot(s)}" | ||
| case s: LocalVarSymbol => doc"${symPrinter.printSymbol(s)}${erasedTypeAnnot(s)}" | ||
| case s: BlockMemberSymbol => doc"${symPrinter.printSymbol(s)}${s.tsym.fold(doc"")(erasedTypeAnnot(_))}" |
There was a problem hiding this comment.
BMS members will have their type info displayed with the actual definition. There's no need to arbitrarily pick the tsym here.
There was a problem hiding this comment.
Ie, it's fine not to display any type for these here.
| /** Refines the erased type, or raises a soft assertion if the type was already previously refined. */ | ||
| def refineErasedType(newType: ErasedType)(using Line, FileName, Raise): Unit = | ||
| softAssert(erasedType.isEmpty, s"Cannot refine already-refined erased type $erasedType to $newType") | ||
| // TODO(Derppening): Restore `erasedType.isEmpty` once JS sanitization is converted into a pass |
There was a problem hiding this comment.
Note: this comment is impossible to understand in isolation. Should say "once JS sanitization is converted into a pass, allowing us to only lower each program once".
| case AnyRef(rsc: Bool, csym: ClassLikeSymbol | NoSymbol) | ||
|
|
||
| /** A reference to a function of a possibly-known shape. */ | ||
| case FuncRef(sig: Opt[Ls[Opt[ErasedType]] -> Opt[ErasedType]]) |
There was a problem hiding this comment.
Cute use of ->, but having two separate fields will be cleaner (and more efficient).
| * The parameters of curried functions are flattened into a single list: this is lossy | ||
| * for the arrow shape but does not affect the rendered return type, the only consumer | ||
| * today. An unannotated return remains `N` (refined in a later phase). */ | ||
| private def refineFunDefnType(tsym: TermSymbol, paramLists: Ls[ParamList], sign: Opt[Term]): Unit = |
There was a problem hiding this comment.
Can we stop calling this process "refine"?
No description provided.