-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Monomorphize generic types #660
Draft
CohenArthur
wants to merge
19
commits into
master
Choose a base branch
from
monomorphize-types
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains 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
This issue we have of bindings/typed values being weirdly linked together by name resolution is really annoying. how do we deal with that. we need to clarify exactly what is a Binding and a TypedValue in the FIR because it feels like a very weak point of the IR |
CohenArthur
force-pushed
the
monomorphize-types
branch
4 times, most recently
from
March 23, 2024 23:41
34acf42
to
ec95b99
Compare
CohenArthur
force-pushed
the
monomorphize-types
branch
from
September 30, 2024 11:49
1088161
to
39cf186
Compare
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.
Needs #662
Rebased on #662 this now reaches
Actual
, so theTreeLike
visitor is working!How do we want this to work? Something like collect all the things that need to be monomorphized, mono them and then recreate the links in the FIR?
E.g if we have
foo(15)
will be a generic call, so we'll mono the function we're calling into - but then we need to mono each of its statements(this is similar for types etc)
so we want our Mono call to return the new OriginIdx we'll be resolved to
e.g.
foo(15)
currently resolves tofoo[T]
, so we'll mono and createfoo[int]
which will return a new OriginIdxthen, we want
foo(15)
to instead resolve tofoo[int]
this is the same thing for all the statements - currently
foo[T]
statements are [a.bar()
], which is the un-mono'd version wherea
is stillT
.we need to mono that and get a list of mono'd statements back, which we'll assign to
foo[int]
- this is tree-like.should we have a tree-like mapper? how would that even work?
how do we do that properly within the current FIR system?
so this should probably be split into two visitors and one generator
Collect what needs to be mono'd. Create a Map with the expected new OriginIdx, thanks to a counter updated in the visitor
GenericCollector(Map<OriginIdx, (Substitutions, NewOriginIdx)>). This is done through a TreeLike visitor because the subs
are available at the definition level (type/function) but need to be used for all the children (fields/statements)
so this is how we collect them. Each child gets its entry in the map and a copy of the substitutions to perform
Mono all required nodes, basically doing copy paste. does this need to be a Mapper/multimapper? How do we mono based on the kind?
Something like (if to_mono.contains(this) -> mono, return vec![this, mono(this)]
this would work and be quite simple!
Finally, replace all references to their mono'd equivalent - so this is just a mapper, looking at the current ctx and doing a replace when necessary
if (to_mono.contains(this) { this.resolved = to_mono.get(this) });
(1) should be used alongside the constraint builder, which builds constraints for generic functions, but that can be done later?
(2) is a simple multimapper we can do here, and (3) is a super simple mapper which is going to be just a couple functions for function calls and type instantiations. name it MonoReplace?
TODO(Arthur): How to name (1)? SubstitutionBuilder?
wait, is this actually going to work? when we create the substitution builder, we need to recreate tree-like structures in the map, so that nodes are mono'd properly
e.g. we can't just copy over the fields of a type declaration, because then (3) would replace them each time since the FIR is one big linked list
e.g. let's take a look at this:
this is represented as the following FIR:
if we mono on
int
andstring
and just copy over the fields, we'll have this:which will be an issue since our SubstitutionMap will contain something like { 1: Monod(1, int), 2: Monod(2, int) }
or { 1: Monod(1, string), 2: Monod(2, string) }
meaning that when we do perform the generation and replacement we'll have the following:
and
so we actually have to "allocate" (and by that I mean create new OriginIdx) before doing the generation and replacement
so when building the subs map, we need to keep that context alive - and visit a definition point everytime we visit a call point!
NOTE(Arthur): Important! basically our SubstitutionMap will be more something like
Map<OriginIdx, Vec<(Substitutions, NewOriginIdx)>
how does that affect our generator? something like multimapper where we take in Foo[T], a Map { Foo[T]: Foo[int], Foo[string] } and return vec![foo[int], foo[string]]?
do we return the generic version? no, right?