-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
remove 'illegal_floating_point_literal_pattern' future-compat lint #116098
remove 'illegal_floating_point_literal_pattern' future-compat lint #116098
Conversation
(rustbot has picked a reviewer for you, use r? to override) |
Some changes occurred in src/tools/clippy cc @rust-lang/clippy Some changes might have occurred in exhaustiveness checking cc @Nadrieril |
This comment has been minimized.
This comment has been minimized.
rust-lang/rust-clippy#11305 should be reverted if this lint is removed. I haven't really read up on why this won't be a hard error, but would this have a place in clippy, perhaps as a subset of the current lint? I do personally find matching on floats a bit peculiar, albeit prettier, but I have the same issues with Are there any use cases for such a clippy lint? |
Now that I think about it, This would probably be a good enhancement to it, suggesting a guard instead |
Can you also open a PR to the reference to remove the two references to 41620 in https://github.com/rust-lang/reference/blob/master/src/patterns.md? |
rustc does not currently lint against '==' on floats, so I don't think it makes sense to lint against matching on floats in general. I did make sure that the NaN comparison lint works for match as well.
I don't really have an opinion on what Clippy should do.
|
The current behavior is "behave like I agree that this PR needs to go through t-lang discussion. |
5c5afca
to
6e4a616
Compare
_ => {} | ||
} | ||
#[expect(invalid_nan_comparisons)] | ||
let _b = x == f32::NAN; |
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 tried to keep this the same as the other copies of the file, but the clippy test is somehow different, ad that doesn't work. It says rustfix failed. I didn't see any other useful information, I just did random mutation of the test file until the clippy test suite passed...
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.
Looks fine to me. The purpose of this test is to check the expect
attribute, which lint the test expect
s shouldn't really matter.
@rust-lang/lang in #84045 you decided to not turn "match on float" into a hard error. However, we kept emitting a lint which said that we would eventually make this a hard error. Clearly that's not consistent, so this PR proposes to remove the lint. However, there's not a ton of rationale discussed in that thread. We have people saying they are matching on floats and see no reason why that would be rejected; we have the point that OTOH, RFC 1445 is fairly clear about rejecting floats in patterns due to them being "not structural" (e.g., So would be good to see if you are still feeling the same way about making this a hard error or not, and why. I don't personally have a preference either way, I just don't want to have a lint that says "will be made a hard error" when at the same time a PR that makes it a hard error gets rejected saying "actually we don't want to make this a hard error". :) |
2296503
to
afe7676
Compare
This comment was marked as duplicate.
This comment was marked as duplicate.
For reference, I've answered this in zulip: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/matching.20and.20.60Eq.60/near/392838566
(emph. mine)
Totally agree, we should make some decision here :) |
☔ The latest upstream changes (presumably #115893) made this pull request unmergeable. Please resolve the merge conflicts. |
Marking as
S-waiting-on-team
|
The proposed design meeting rust-lang/lang-team#220 is also relevant (though all of the designs proposed there can make floats work, some might want to restrict matching to non-NaN floats or something like that). |
The following is based on my zulip message, where Ralf asked me to expand on those thoughts here.
Neither must apply to Match maps a value to a branch based on an ordered list of set specifiers (patterns): sometimes the set is a single value, multiple discrete values, a range, a union of those, etc. That's all to say that pattern matching and equivalence are quite different concepts and don't need to behave identically. In fact, sometimes we want or need them to behave differently in order to achieve the desired In my opinion, the ideal version of float matching would be: match some_float {
f32::INFINITY => "positive infinity",
f32::NEG_INFINITY => "negative infinity",
+0.0 => "positive zero",
-0.0 => "negative zero",
f32::MIN_POSITIVE.. => "positive normal",
..=-f32::MIN_POSITIVE => "negative normal",
+0.0..f32::MIN_POSITIVE => "positive subnormal",
-f32::MIN_POSITIVE..-0.0 => "negative subnormal",
_ => "not a number",
} Just And forbid matching individual NaN values: // error: matching on individual NaN values is not allowed
f32::NAN => "this particular NaN",
// error: matching on individual NaN values is not allowed
f32::NAN..=f32::NAN => "this particular NaN", One hitch with the above is that float matching currently uses
One possibility for the future is enabling some way to create a pattern that matches
|
Thanks for writing this up!
That's a very strong statement. IMO it is totally reasonable to apply this to match semantics, it just doesn't match your mental model. |
I don't think we ever want to have a situation where there is a I also think most people that don't know much about floats (and don't even know that 0 has a sign) would be very surprised if |
Also marking as "blocked", I think we want to make matching on NaN a hard error (and we've future-compat linted against it for a long time so we should be able to do this reasonably fast). |
To be clear, I did not mean "both must NOT apply to match semantics" but rather "these don't necessarily have to apply to match semantics as well". For instance, my proposal does not allow matching on individual NaNs - just like how PartialEq does not find them equal.
I agree that it's not pretty. But under this option, putting
To be clear, the pattern |
Ah I see, thanks for clarifying.
But if I have Also, you're still taking for granted that 0.0 and +0.0 are not the same thing. That's already a totally outlandish idea if you're not well-versed in the binary representation of floats. If a programmer wrote |
I think it should eventually be possible to match every float value individually. Positive and negative zero are fundamental different values and will have different divide-by-zero results. So I think being able to match on them separately is valuable. That said, it's not super important to me. If it's far more practical to have
I think matching a certain const should only ever match that exact value. So One benefit of that behavior is that you get the practical benefits of the pattern That would mean that the pattern is slightly inconsistent from the literal value, but since zero is a special case anyways, and the only case where this happens, I think that's acceptable. |
Un-nominating for now in lieu of the upcoming lang team meeting, rust-lang/lang-team#222. @rustbot label -I-lang-nominated |
If we follow the proposal in rust-lang/rfcs#3535, we should first land #116284 and then remove the lint. |
I have folded this PR into #116284. |
In #84045 the lang team rejected making this a hard error. So clearly we shouldn't have a lint saying "this will be a hard error in the future".
TODO:
Fixes #41620