Skip to content
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

Open
wants to merge 24 commits into
base: trunk
Choose a base branch
from

Conversation

danakj
Copy link
Contributor

@danakj danakj commented Feb 28, 2025

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.

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.
@github-actions github-actions bot requested a review from dwblaikie February 28, 2025 23:45
@danakj danakj requested review from josh11b and removed request for dwblaikie February 28, 2025 23:45
Copy link
Contributor

@josh11b josh11b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Progress!

danakj and others added 11 commits March 3, 2025 11:44
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>
@danakj danakj requested a review from josh11b March 3, 2025 16:58
Copy link
Contributor Author

@danakj danakj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! PTAL

@danakj danakj requested a review from josh11b March 4, 2025 19:04
Copy link
Contributor Author

@danakj danakj left a 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) {
Copy link
Contributor

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) {
Copy link
Contributor

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.

danakj and others added 2 commits March 4, 2025 15:25
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
@danakj danakj requested a review from josh11b March 4, 2025 21:02
@danakj
Copy link
Contributor Author

danakj commented Mar 4, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants