-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Make coherence more tolerant of error types. #30676
Conversation
r? @Aatch (rust_highfive has picked a reviewer for you, use r? to override) |
@arielb1 in case it wasn't clear, this is what I meant -- thoughts on which approach is overall better? Incidentally, I do agree that refactoring projection to be explicitly fallible is probably a good idea (versus the current "return an obligation that is known to result in an error"). |
I feel that the handling of |
Do you mean specifically the way the projection code injects a TyError and an "obligation that should yield an error"? If so, I agree -- TyError ought to only be used when an error has been reported, and it violates that rule. |
Added two new tests for other scenarios. I am torn here, in that I do feel this approach is how |
☔ The latest upstream changes (presumably #30317) made this pull request unmergeable. Please resolve the merge conflicts. |
@arielb1 so take a look at that last commit. I changed the |
Hmm, that branch seems to fail compile-fail. No time to look at why that is just ntke though. |
Just NOW |
The code is an rpass in my branch (and my simplified example). I think that improving |
Well, I see, the problems are just (as might be expected) that we get some derived errors we ought not to be seeing (because we are no longer returning |
If this is so simple, I'll r+ if you fix the errors. I also prefer that you use this simplified testcase: pub trait Foo { type Output: 'static; }
pub trait Bar<P> {}
pub trait Baz<P> {}
impl<T: 'static, W: Foo<Output=T>> Baz<*mut T> for W {}
impl<P, T: Baz<P>> Bar<P> for T {}
impl<T> Bar<*mut T> for [T; 1] {}
fn main() {} |
The reordering fix also seems to resolve the ICE, but I like yours better. |
@arielb1 So i've been thinking about this all morning and digging through logs. I think I have now come to the conclusion that indeed the only non-scary fix is to stop having First off, the general strategy with Now, the code in However, what coherence is interested in is actually a different predicate. Using RFC 1144 syntax, coherence is really evaluating There are in fact other situations where this crops up. The current technique for handling them is checking the So now, your original patch made me uneasy because At some point I was considering that we could just make Scary thought the first. PR #30533 introduces some logic like the following: if we see an error evaluating obligation X occurring in tree Y, we can ignore all further pending obligations in tree Y, because we know that tree Y will never succeed. However, that would be incorrect in the face of the Scary thought the second. The whole logic relies on the idea that we will report an error when we later encounter the obligation that failed to resolve. But in this case (and I think we saw this before), the projection itself is part of that trait reference. That is, we have a constraint like So now the question becomes: can we suppress the derived error reporting in some useful way? Initially I had the thought that we could resolve to the projection but record the projection in the Therefore, right now, I am leaning towards not suppressing the derived errors. They are sort of comprehensible anyhow. In the future, I would like to move towards lazy normalization (enabled by #30533 in any case), which would give us a chance to overhaul the normalization and |
@arielb1 I feel like scary thought the second is something we discovered already and I just forgot about. Is that true? Do you remember? |
Oh, well, obviously that is true, given that the comment that I myself removed talks about it. Well, yeah, it's not good. |
Hmm, I just got to thinking. In the cyclic case, is it possible that unifying will still leave us in an exposed position? Surely it's better to unify with |
OK, I found a strategy I like. I am now substituting a fresh inference variable. This seems to avoid all the hazards I was concerned about. I've got a PR that works great except that |
Yes, I was definitely aware of scary thought the second (the reason it is not an issue in practice is subtle - the check for I feel that normalizing to the projection is fine - after all, this is what we often do when the projection contains type parameters, so the cascading error messages are not that unusual. Maybe we should just split the normalize-to-type and normalize-and-unify paths somehow, and either normalize to a projection or not unify the resulting predicate. The ICE in #4972 slightly scares me - we should investigate it. |
Of course, if unifying types causes more impls to be available, this can cause errors in other ways. |
4303a85
to
ef270e4
Compare
…stead of `TyError`
the problem is that now "type_is_known_to_be_sized" now returns false when called on a type with ty_err inside - this prevents spurious errors (we may want to move the check to check::cast anyway - see rust-lang#12894).
ef270e4
to
83710b4
Compare
r? @arielb1 |
This latest version now passes
I guess the last point might be silly, it does mean that we'll keep this obligation hanging around for longer. |
|
||
// Eagerly check for some obvious errors. | ||
if t_expr.references_error() { | ||
if t_expr.references_error() || t_cast.references_error() { | ||
fcx.write_error(id); | ||
} else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) { |
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.
Die!
@bors r+ |
📌 Commit b0f6a47 has been approved by |
@bors p=1 (upping priority for regression fixing or beta-nominated PR's) |
⌛ Testing commit b0f6a47 with merge 19d8f46... |
💔 Test failed - auto-linux-64-nopt-t |
@bors retry |
This is an alternative to #29954 for fixing #29857 that seems to me to be more inline with the general strategy around `TyError`. It also includes the fix for #30589 -- in fact, just the minimal change of making `ty_is_local` tolerate `TyError` avoids the ICE, but you get a lot of duplicate error reports, so in the case where the impl's trait reference already includes `TyError`, we just ignore the impl altogether. cc @arielb1 @sanxiyn Fixes #29857. Fixes #30589.
Accepting for beta since this addresses a regression. |
This is an alternative to #29954 for fixing #29857 that seems to me to be more inline with the general strategy around
TyError
. It also includes the fix for #30589 -- in fact, just the minimal change of makingty_is_local
tolerateTyError
avoids the ICE, but you get a lot of duplicate error reports, so in the case where the impl's trait reference already includesTyError
, we just ignore the impl altogether.cc @arielb1 @sanxiyn
Fixes #29857.
Fixes #30589.