-
Notifications
You must be signed in to change notification settings - Fork 183
Handle bound vars in builtin trait impls #463
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
Handle bound vars in builtin trait impls #463
Conversation
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.
Does this end up being more work for SLG? This seems right. But an alternative solution might be to make the recursive solver "generalize" all the program clauses.
The builtin impls have the same problem that the dyn trait impl did, which is that they reuse the trait ref as given. The problem with that is that the recursive solver calls `program_clauses` with trait refs that contain bound vars from the original goal. So the builtin impls returned clauses with free bound vars, which is a problem. The solution is the same as for the dyn trait impls: Use the `Generalize` folder to collect those free bound vars and basically put a `forall` around them. To give an example: Looking for ``` Implemented((^0.0, ^0.1): Sized) ``` previously returned something like ``` if (Implemented(^0.1: Sized)) { Implemented((^0.0, ^0.1): Sized) } ``` as a clause; now it returns ``` forall<type, type> if (Implemented(^0.1: Sized)) { Implemented((^0.0, ^0.1): Sized) } ``` (The SLG solver instantiates goals before asking for program clauses, so it has inference variables instead of bound vars in those places.)
99fcb47
to
35a0647
Compare
It might be slightly more work, but it's just a no-op fold instead of a clone, which I would think should not be much slower. |
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.
So the code here looks right to me. Can you file an issue for the builtin type enumeration for followup?
I'm still a bit wary on whether this is a better solution compared to the alternative I suggested. So maybe @nikomatsakis can take a quick look?
I'm not a fan of doing this for all program clauses because most program clauses don't actually need it. It's only when we take full types from the goal that it becomes necessary. It would actually be possible to write the builtin clauses code in a way that doesn't require this either (instead of a clause for e.g. the specific tuple type always generate a clause for all tuples of the given cardinality), this is just a bit easier. |
I'm convinced. |
The builtin impls have the same problem that the dyn trait impl did, which is
that they reuse the trait ref as given. The problem with that is that the
recursive solver calls
program_clauses
with trait refs that contain bound varsfrom the original goal. So the builtin impls returned clauses with free bound
vars, which is a problem. The solution is the same as for the dyn trait impls:
Use the
Generalize
folder to collect those free bound vars and basically put aforall
around them. To give an example:Looking for
previously returned something like
as a clause; now it returns
(The SLG solver instantiates goals before asking for program clauses, so it has
inference variables instead of bound vars in those places.)