-
Notifications
You must be signed in to change notification settings - Fork 182
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
experiment with converting semantic to syntactic equality #364
Comments
OK, it took me some time to find, but I finally found a link to the meeting where we discussed this topic in some depth. It was the meeting on 2019.10.16. So, to start, you can read those notes to get a high-level idea of what's being proposed. I'll paste in the key idea here. How it works todayToday, given an impl like this impl<T: Iterator> Foo for T::Item { .. } we would generate a clause like
Then, when we do unification, we look for types like chalk/chalk-solve/src/infer/unify.rs Lines 221 to 237 in 2bd2e03
So what happens is that we dynamically unfold the rule above. i.e., if we are matching against a goal like Why is this ungreat?There are a few problems with this setup. First, as a general rule, I'd like the "solving logic" phase to be as simple as possible -- and our current unification scheme, which doesn't just unify types but also injects goals, makes things more dynamic and less amenable to (say) compilation in the future. In other words, I want the solving phase to be very close to prolog, and right now it's not. But second, I want to create the invariant that whenever we ask for "all the impls of a trait", we have some idea what the "self type" is. This is helpful to things like rust-analyzer and rustc, since they can index impls by self-type and retrieve them more efficiently. But when we are solving a goal like There's a third reason, but I'm not sure how much it applies given the work on the recursive solver. Still, one of the things I was exploring was a different model for region solving, and for that to work, I had to be able to separate out cases where I wanted to first regions that were syntactically equal (so How I would like it to workI mentioned that today we unfold the goals dynamically as we unify things. There are two parts to the work here. The first part is that for an impl like the previous example: impl<T: Iterator> Foo for T::Item { .. } we would generate a clause like:
The second part is that we would have to unfold goals as well. So something like Implemented(<T as Iterator>::Item: Foo) would become exists<X> {
AliasEq(<T as Iterator>::Item = X),
Implemented(X: Foo)
} In fact, I wrote up the transformation in some detail in a branch. I'll copy and paste that comment below for posterity. |
Here is the comment from my branch, just in case that file gets lost. The "syntactic equality" lowering converts Rust semantic type Syntactic vs semantic equalitySo, what is the difference between syntactic vs semantic equality?
The transformation this module performsThis module takes program clauses and goals and converts them Example: transforming a program clause with repeated lifetimesConsider the following trait/impl: trait SomeTrait<T> { }
impl<'a> SomeTrait<&'a u32> for &'a u32 { } The equivalent program clause for this impl would be:
This program clause, however, assumes semantic equality -- that is,
The Example: transforming a program clause with associated typesConsider the following trait/impl: trait SomeTrait<T> { }
impl<T: Iterator> SomeTrait<T::Item> for T { } The equivalent program clause for this impl would be:
Again, this assumes semantic equality, as it contains
The pattern should look familiar: we just introduce a variable and add Example: transforming a goal with associated typesContinuing the previous example, imagine that we have a goal that fn foo<T>()
where
T: Iterator,
T: SomeTrait<T::Item>
{ } In that case, we have to prove
This goal assumes semantic equality. We can transform it goal into syntatic equality like so:
Generalizing: the rules to convert from syntactic to semantic equalityThe general rules for converting from syntactic to semantic equality
The rule
|
A few things have changed since I pursued my older syntactic-equality branch:
I know I had another branch where I actually did complete the "semantic to syntactic" transformation, but only for clauses, and it didn't quite work. I might try to go find it, but perhaps the syntactic-equality branch is enough. |
@rustbot claim |
This issue has been assigned to @Areredify via this comment.
The text was updated successfully, but these errors were encountered: