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

Replace fallback clauses with projection-equality vs normalization #75

Merged
merged 8 commits into from
Jan 20, 2018

Conversation

nikomatsakis
Copy link
Contributor

@nikomatsakis nikomatsakis commented Jan 19, 2018

Fixes #74

Before merging, I should do a few things:

  • cleanup history
  • comment the SLG AnswerSubstitutor code
  • actually remove fallback (it's still present, just unused)

Not really the ideal solution, but helpful. It'd be nice to record all
the data and be able to expand after the fact.
src/lower/mod.rs Outdated
// we generate the 'fallback' rule:
//
// forall<T> {
// proj <T as Foo>::Assoc = Foo::Assoc<T>
Copy link
Member

Choose a reason for hiding this comment

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

I’m not sure why we don’t need a :- T: Foo condition here, especially looking at the reverse rule below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Although currently I've hacked out that reverse rule, the comment is out of date, and instead made T: Foo part of the "WF" criteria (which I guess is your answer). Still, it seems like otherwise I suppose we would need that.

@nikomatsakis
Copy link
Contributor Author

OK, @scalexm, I changed the fallback rule as you suggested, which doesn't seem to cause any problems (I didn't think it would). I also wrote comments.

I didn't really clean up the history that much, not sure that I care enough to do so. Inclined to merge soon.

@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Jan 20, 2018

ok, I cleaned it up a little more

Instead of having "fallback clauses" to handle projection, we now
have `ProjectionEq(<T as Trait>::Bar = U)`, which can be proven
either by normalizing *or* by skolemizing.

This required adjusting how we handle elaboration. That is, we now
"expand" a `T: Trait<Bar = U>` (which is the user syntax for projection
equality) into `T: Trait` as well, which in turn expands into `WF(T:
Trait)`. We do this instead of having a clause like:

> `(T: Trait) :- exists<U> { (T: Trait<Bar = U>) }`

This is because that clause caused issues for the recursive solver; in
particular, `exists<U> { (T: Trait<Bar = U>) }` always resolves to an
ambiguous result, since there is no unique `U`.

This PR adjusts the tests appropriately. Mostly we add normalize and
projection. In a few cases, the SLG solver doesn't work yet; those are
tagged with FIXME (and fixed in a later commit).
This is not only more efficient, but it also sidesteps the problems that
led to the SLG solver recursing infinitely when unifying goals involving
projections.

This also uncovers a potential flaw with the truncation operation, in
that it does not concern itself with internal binders. For example, we
might truncate a type like `for<'a> fn(Vec<&'a u32>)` into `for<'a>
fn(?X)`. This is problematic because there is no value of `?X` that
could reference `'a`. For now, the SLG solver will panic in this
scenario, but probably truncation needs to truncate the binder as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants