-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Add warning for () to ! switch #39009
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Can someone help me figure out what's causing that error? Coz I'm lost :( It's coming from this line: https://github.com/canndrew/rust/blob/8940922e830dce009cce547a8bc488134803ee8e/src/librustc_trans/symbol_map.rs#L70 If I print out
Edit: Thanks @eddyb for solving it. |
I think future compatibility warnings are supposed to have tracking issues now (ex: #38260). |
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.
This looks pretty reasonable! We will need a test or two, though, and I left a few nits.
src/librustc/traits/select.rs
Outdated
// Test whether this is a `()` which was produced by defaulting a | ||
// diverging type variable with `!` disabled. If so, we may need | ||
// to raise a warning. | ||
if let ty::TyTuple(_, true) = obligation.predicate.skip_binder() |
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.
Nit: can you extract this into a helper function?
src/librustc/traits/select.rs
Outdated
if raise_warning { | ||
let sess = tcx.sess; | ||
let span = obligation.cause.span; | ||
let mut warn = sess.struct_span_warn(span, "code relies on type inference rules \ |
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.
This should be a proper future-compatibility lint. RFC 1589 describes the general idea of how a future compatibility lint works. In terms of the code, you can ripgrep around for LIFETIME_UNDERSCORE
to see how the lint is defined.
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.
I've added a new future-compatibility lint resolve_trait_on_defaulted_unit
. However it comes with the message "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" which, for this warning, isn't exactly true. Does this matter?
{ | ||
if as_.len() == bs.len() { | ||
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?) | ||
let defaulted = a_defaulted || b_defaulted; |
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.
Hmm, I wonder if this should be a_defaulted && b_defaulted
? My thinking is this: if we are relating two ()
values, and one of them came directly from the user, then that type will continue to be ()
even when !
fallback is changed. Probably it doesn't matter because in such a case the fallback won't actually trigger anyhow.
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.
Yeah, I couldn't see when it would ever matter so I decided to err on the side of creating more warnings.
@nikomatsakis We should probably crater this before merging it. I'm curious to see what the fallout is. |
Is there any chance of getting this into the next release or is it far too late? I'd like to start raising these warnings as soon as possible. |
@canndrew not sure, sorry I'm a bit delayed, was out of town last week. Regarding crater, not a bad idea. Probably best would be to crater a version where the warnigns are set to deny-by-default so we can identify the affected crates most accurately. |
@nikomatsakis |
@canndrew one thing, can you add a more straight-forward test to the PR? The existing test works because of how we desugar |
☔ The latest upstream changes (presumably #39305) made this pull request unmergeable. Please resolve the merge conflicts. |
2b10dc2
to
3b3fe61
Compare
I changed the test to use |
☔ The latest upstream changes (presumably #39230) made this pull request unmergeable. Please resolve the merge conflicts. |
@canndrew I had some technical difficulties, but here are the results:
|
Of the two affected crates, the second one seems to be the |
@canndrew that test will do, I suppose, but I was thinking of a test where the type is in fact part of dead-code. I think something like this has been found in the wild (and it currently type-checks): fn foo<T: ::std::fmt::Debug>(_: T) { }
fn main() {
let x = return;
foo(x);
} |
I think the issue in question is #39297. |
Ay, more broken crates :( I really hope we can get this warning into the next release. I'll PR the the two affected libraries.
Depends what you mean by "spurious". Even if that's going to become an error for another reason, we still need to warn about it. |
This PR deliberately checks for cases like that and doesn't raise a warning. The |
3b3fe61
to
40c9538
Compare
Do you mean because |
@bors r+ |
📌 Commit 40c9538 has been approved by |
In any case, I'm happy enough with this, and sick of waiting. Let's land this already. =) |
⌛ Testing commit 40c9538 with merge dd7ee9d... |
💔 Test failed - status-travis |
Ah, I getchya. I've added it to the test. |
@bors: r=nikomatsakis |
📌 Commit 42f3ac5 has been approved by |
…ikomatsakis Add warning for () to ! switch With feature(never_type) enabled diverging type variables will default to `!` instead of `()`. This can cause breakages where a trait is resolved on such a type. This PR emits a future-compatibility warning when it sees this happen.
…ikomatsakis Add warning for () to ! switch With feature(never_type) enabled diverging type variables will default to `!` instead of `()`. This can cause breakages where a trait is resolved on such a type. This PR emits a future-compatibility warning when it sees this happen.
With feature(never_type) enabled diverging type variables will default to
!
instead of()
. This can cause breakages where a trait is resolved on such a type.This PR emits a future-compatibility warning when it sees this happen.