Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upTracking issue for `illegal_floating_point_literal_pattern` compatibility lint #41620
Comments
est31
added a commit
to est31/rust
that referenced
this issue
Apr 29, 2017
est31
added a commit
to est31/rust
that referenced
this issue
Apr 29, 2017
est31
added a commit
to est31/rust
that referenced
this issue
May 2, 2017
bors
added a commit
that referenced
this issue
May 8, 2017
frewsxcv
added a commit
to frewsxcv/rust
that referenced
this issue
May 9, 2017
frewsxcv
added a commit
to frewsxcv/rust
that referenced
this issue
May 9, 2017
hackeryarn
added a commit
to hackeryarn/rust
that referenced
this issue
May 9, 2017
This comment has been minimized.
This comment has been minimized.
|
RFC 1445 is about |
This comment has been minimized.
This comment has been minimized.
|
This is a breaking change (rejecting previously-accepted programs) but as far as I can tell this one is not part of an accepted RFC. |
This comment has been minimized.
This comment has been minimized.
|
Is this a duplicate of #36890? |
This comment has been minimized.
This comment has been minimized.
Hmm a quick glance over the RFC seemed to confirm this.
No, its separate. There are two separate lints. This one is about literals, the one tracked in that issue is about constants. I have opened the PR #41293 after finding out about #41255. |
This comment has been minimized.
This comment has been minimized.
From my perspective, primitive literals (as opposed to destructuring struct literals) are a kind of constant. The same questions raised by consts in that RFC are raised by primitive literals. |
This comment has been minimized.
This comment has been minimized.
Yet the example given in #36890 uses literals.
Given that we have a language keyword named |
This comment has been minimized.
This comment has been minimized.
The example quoted in the tracking issue you linked never was implemented that way. I have asked about whether to create a separate lint or add the check to the existing one, and it was decided to create a separate lint. I guess the example should be removed from that issue's description. |
This comment has been minimized.
This comment has been minimized.
|
I would definitely say that the RFC was intended to apply equally to all constants, whether they are literals or not. Clearly there is room for other opinions (since @SimonSapin read it differently). Personally, I am on the fence here. I somewhat agree with @SimonSapin that the number of regressions here feels too high. Part of the reason that I agree to go with a warning was to highlight this question so that we can have a wider discussion with more of the people who are affected. For clarity, floating point literals at present match the same way as I take the following as a given (I'm curious if others disagree):
This seems to imply that if we don't make things a hard error, we can't have floating point NLC that use a purely structural match. They would always match with This may or may not affect plans around constant generics. It's not obvious to me that dynamic In other words, I see a few options:
I am not sure whether an RFC ought to be required, whichever path we chose, but since there seems to be disagreement, it seems plausible to open an RFC amendment to finalize the decision. |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I don't think this needs to be entangled with const generics, we just need to transition to a solution for that as well as whatever we decide for match. Just renaming the attribute is probably fine. I do feel that literals and consts should behave the same, but I don't have a strong opinion about how they ought to behave. Really whatever decision seems fine if it applies to both. |
This comment has been minimized.
This comment has been minimized.
Let me unpack this a bit to be sure I understand. You're saying:
Right? (That said, it's not entirely clear to me why const generics would even need an attribute at all; I guess it depends a lot on how we wind up defining equality. My expectation was that equality would be based more on where in the source the expression arose (i.e., we would treat constant expressions as kind of "uninterpreted functions") -- and we'd always be assuming that said functions are deterministic (because of the limits we place on const fns), and hence we consider two constant expressions "equal" if they are the same function applied to equal inputs, where this bottoms out with simple integers and other builtins. But I guess eventually we might want to extend that notion of structural equality to other kinds of expressions and types, and maybe we want some opt-in around that, unsure.) |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis the issue here isn't with unevaluable const expressions but with floating point numbers and other types for which equality is not reflexive because of how that would impact unification. We don't need an attribute but it does seem that we do need const values to have a guaranteed reflexive definition of equality (which is why just using |
nikomatsakis
referenced this issue
May 11, 2017
Closed
Matching on floating-point literal values is totally allowed and shouldn't be #41255
rillian
referenced this issue
May 16, 2017
Closed
Internal compiler error: broken MIR in gecko_bindings #42042
This comment has been minimized.
This comment has been minimized.
darkwater
commented
May 23, 2017
•
|
I might be missing something here, but I see this also applies to ranges, ie.
gives warning: floating-point literals cannot be used in patterns. Is this intentional? I feel like this is a pretty common pattern. |
This comment has been minimized.
This comment has been minimized.
|
Yeah, I gotta ask, how am I supposed to do clean pattern matching with floating point ranges. I know floating points are hard, but isn't there a way to make this work in ranges? Example (real) code that gives a warning now: /// Calculates the UTM zone this longitude falls in
/// Handles exceptions for Norway / Svalbard
/// For a visual representation: https://upload.wikimedia.org/wikipedia/commons/a/a5/UTM-Zone.svg
///
/// Inputs: Longitude, in degrees
/// Latitude, in degrees
///
/// Returns: UTM Zone
///
#[allow(non_snake_case)]
pub fn get_utm_zone(lon: f64, lat: f64) -> u8 {
let mut zone = ((lon + 180.0) / 6.0).floor() as u8 + 1;
match lat {
56.0..64.0 => {
/* Zone V, Norway */
match lon {
3.0..6.0 => {
zone += 1;
}
_ => {}
}
}
72.0..84.0 => {
/* Zone X, Svalbard */
match lon {
6.0..9.0 => {
zone -= 1;
}
9.0..12.0 => {
zone += 1;
}
18.0..21.0 => {
zone -= 1;
}
21.0..24.0 => {
zone += 1;
}
30.0..33.0 => {
zone -= 1;
}
33.0..36.0 => {
zone += 1;
}
_ => {}
}
}
_ => {}
}
zone
}How should I write this instead? Why is it that I can do comparisons of floats in if statements, but not pattern matching in range statements? I would have to write |
This comment has been minimized.
This comment has been minimized.
|
@darkwater @sharazam
Yes, there has been some back and forth on whether we ought to apply the same thing to floating points. |
This comment has been minimized.
This comment has been minimized.
|
It would be very unfortunate if floating point ranges were disallowed by this. I don't see any problems with this particular pattern. |
nikomatsakis
added
B-unstable
T-lang
labels
May 25, 2017
ordovicia
referenced this issue
May 28, 2017
Closed
Fix `illegal_floating_point_literal_pattern` warning #652
This comment has been minimized.
This comment has been minimized.
|
I was caught by this as well. My case is: let fudge_factor = match magic_value {
0. ... 0.8 => 9.,
0. ... 1.0 => 6.,
0. ... 1.2 => 4.,
0. ... 2.5 => 3.67,
_ => 3.0,
};To work around float comparison woes I'm using a hack of starting every range with I don't particularly like the current hacky/unclear/error-prone way of matching non-overlapping ranges of numbers, but I'd rather have something working until Rust gets a better replacement. |
bvssvni
added a commit
to bvssvni/image
that referenced
this issue
Jun 12, 2017
Mark-Simulacrum
added
the
C-future-compatibility
label
Jun 24, 2017
This comment has been minimized.
This comment has been minimized.
|
I waded through three or four threads to find the rationale for this (found it here: #20489, in a comment dated Jul 18, 2015). Niko Matsakis wrote: "right now, you can match on types that don't implement PartialEq at all, and if they do implement it, the match code semantics do not align with what PartialEq implements. This seems bad. Having match x { FOO => ... } and match x { y if x == FOO => } both be accepted but different in subtle ways seems clearly suboptimal to me." Now I can understand (and agree with) the motivation; I thought I'd post this here in case others were looking for it too. |
Mark-Simulacrum
added
C-tracking-issue
and removed
C-tracking-issue
labels
Jul 22, 2017
tynril
added a commit
to tynril/capnpc-rust
that referenced
this issue
Jul 30, 2017
tynril
referenced this issue
Jul 30, 2017
Merged
Not using `match` on floating point values anymore. #40
jerneyio
referenced this issue
Sep 13, 2017
Merged
Fix floating-point literal used in pattern in example #705
pixelistik
added a commit
to pixelistik/aggregated_stats
that referenced
this issue
Oct 8, 2017
pnkfelix
added a commit
to pnkfelix/rust
that referenced
this issue
Aug 31, 2018
pnkfelix
added a commit
to pnkfelix/rust
that referenced
this issue
Aug 31, 2018
pnkfelix
added a commit
to pnkfelix/rust
that referenced
this issue
Sep 3, 2018
pnkfelix
added a commit
to pnkfelix/rust
that referenced
this issue
Sep 6, 2018
pnkfelix
added a commit
to pnkfelix/rust
that referenced
this issue
Sep 6, 2018
iceiix
added a commit
to iceiix/steven
that referenced
this issue
Sep 30, 2018
eliovir
added a commit
to eliovir/rust-examples
that referenced
this issue
Oct 1, 2018
This comment has been minimized.
This comment has been minimized.
blakehawkins
commented
Oct 9, 2018
|
Any update on this? Will float ranges ever get different treatment from matching over equality for float values? |
est31
closed this
Oct 19, 2018
rust-lang
locked and limited conversation to collaborators
Oct 19, 2018
pietroalbini
reopened this
Oct 21, 2018
rust-lang
unlocked this conversation
Oct 21, 2018
LukasKalbertodt
referenced this issue
Nov 12, 2018
Merged
Update dependencies and stuff like that #203
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis How do you feel about crater running this to see if we can drive this to completion in the coming weeks or so? |
This comment has been minimized.
This comment has been minimized.
|
cc #56362 |
This comment has been minimized.
This comment has been minimized.
donbright
commented
Dec 30, 2018
•
|
i feel like if Rust is going to go all-in on treating binary base-2 floats uniquely due to their special nature, then there would be a lot of help for us users if there could be a base-10 Decimal number type included in the base level of the language. . . including base-10-decimal literals, and then let the adventurous and wild amongst us convert willy nilly between base-2 floating points and our decimal literals with some function that we have to unwrap_or() or whatever. . . |
This comment has been minimized.
This comment has been minimized.
anyusernameworks
commented
Mar 5, 2019
|
What if we only care about positive float values? |
est31 commentedApr 29, 2017
•
edited
This is a tracking issue for the compatibility lint disallowing floating point literals in patterns.
The corresponding RFC is RFC 1445. Originally, #36890 was the only tracking issue for floats in patterns, but after it was found out that the implementation of that lint doesn't cover literals (issue #41255), another lint and tracking issue were required.
The goal of this lint is to make code like this a hard error: