-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Support impl lookup for multiple interfaces in a facet type #5047
base: trunk
Are you sure you want to change the base?
Conversation
If the query facet type has more than one interface, we must find an impl that provides that interface for the query type for each interface. This just looks like a for loop over the interfaces and ensuring we found one impl witness for every one. However the impl matching must change since it can't look at the constant value of the entire query facet type for comparison with the impl, as that query facet type may be for multiple interfaces and we are looking to match an impl of a single interface. To do this we break the query facet type up into each interface and make sure the interface ids match. Then ensure that the impl was able to deduce any generic parameters using the specific of the single query interface. There are some TODOs left here: 1. If the facet type for the query or the impl constraint has "other_requirements" then we can't verify that they match since they are lost. We fall back to comparing the constant id of the query to the impl's constraint (after deducing generics in the impl). This correctly eliminates mismatches but eagerly eliminates impls that could match the query interface as well when there's more than one interface in the query. 2. We don't return a witness for every interface in the query facet type. Since we can't demonstrate any use of the witness there yet, for cases that can have more than one interface in the query facet type, this doesn't break anything that was previously working. The return value is currently treated as a bool for cases with multiple interfaces in the facet type (as a test for "can this be converted") but the converted-to facet value's witnesses are unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Progress!
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! PTAL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PTAL
// `impl T as ...` for some other type `T` and should not be considered. | ||
auto deduced_self_const_id = SemIR::GetConstantValueInSpecific( | ||
context.sem_ir(), specific_id, impl.self_id); | ||
if (type_const_id != deduced_self_const_id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this addressed? I think this would be a useful test.
auto deduced_constraint_id = | ||
context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific( | ||
context.sem_ir(), specific_id, impl.constraint_id)); | ||
if (deduced_constraint_id == SemIR::ErrorInst::SingletonInstId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I don't understand the comment and an example would help me figure out what I was missing.
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
The conversation tab seems to not be including my replies to the last 2 comments, idk what's going on with github. So just linking them here: https://github.com/carbon-language/carbon-lang/pull/5047/files#r1980184279 https://github.com/carbon-language/carbon-lang/pull/5047/files#r1980207616 |
If the query facet type has more than one interface, we must find an impl that provides that interface for the query type for each interface. This just looks like a for loop over the interfaces and ensuring we found one impl witness for every one.
However the impl matching must change since it can't look at the constant value of the entire query facet type for comparison with the impl, as that query facet type may be for multiple interfaces and we are looking to match an impl of a single interface.
To do this we break the query facet type up into each interface and make sure the interface ids match. Then ensure that the impl was able to deduce any generic parameters using the specific of the single query interface.
There are some TODOs left here:
If the facet type for the query or the impl constraint has "other_requirements" then we can't verify that they match since they are lost. We fall back to comparing the constant id of the query to the impl's constraint (after deducing generics in the impl). This correctly eliminates mismatches but eagerly eliminates impls that could match the query interface as well when there's more than one interface in the query.
We don't return a witness for every interface in the query facet type. Since we can't demonstrate any use of the witness there yet, for cases that can have more than one interface in the query facet type, this doesn't break anything that was previously working. The return value is currently treated as a bool for cases with multiple interfaces in the facet type (as a test for "can this be converted") but the converted-to facet value's witnesses are unused.