-
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
Clarify ambiguity during unification; overhaul normalization fallback #38
Conversation
Some thoughts:
At first, I thought the idea was that the "ground truth" derives from the set of impls -- and I guess it might be fruitful for us to try to specify what a "correct" result means for our logic in some way that takes this into account. But just because clauses are in the program doesn't necessarily make them fit this definition. For example, in #12, we are talking about adding program clauses to handle "supertrait implications" (e.g. that I guess at the end of the day it just feels sort of inconsistent to say that we can ignore I am wondering how the "closed world" notion that we are using here would interact with (e.g.) coherence checking. Do we need different assumptions there? In that case, we (sometimes) have to assume that there might be more impls/types we don't know about, right? (e.g., in this case, it's very possible) |
@nikomatsakis Thanks for the thoughtful comments!
Yes, I agree with all of this. What I meant by "no forward progress on the goal is possible" is just that, in terms of what we're yielding up, there's no action that can be taken to "unblock" us. But of course our goal might be in the context of another Thinking more about
I think this is just a bug. If we go this route, I'll re-work it.
Yes, exactly; this is what I had been thinking, but failed to articulate. Note that things work fine even if we remove this special-casing; it just changes some inference heuristics. Here's a good case to keep in mind: trait Foo {}
struct i32 {}
impl Foo for i32 {}
forall<T> { T: Foo }
forall<T> { not { T: Foo } } It's vital here that we treat
Yes, this is precisely what the compat modality is about -- literally changing the statement from being about the current world (which we can assume is fixed) to all compatible ones. |
OK, since @aturon is on PTO for this week, and I want to unblock stuff, I'm going to land this PR and open an issue to discuss follow-up changes. |
This PR makes a few important changes:
It clarifies ambiguity during unification so that we understand a query like
!0 = i32
or!0 = !1
as asking the question for all possible substitutions, meaning that we can neither prove nor refute it, and hence return an ambiguous result.Furthermore, we treat program clauses as comprising a closed world (as intended) that cannot be extended further through environmental assumptions. That means, in particular, that we can simply ignore environmental assumptions that would require ambiguous unification to employ.
Rather than using negation for normalization fallback, we introduce an explicit notion of "fallback program clauses" which are employed only when it is clear that no other forward progress on the goal is possible.