rust-lang / rust-lang/rust-clippy
New lint for platform-dependent or nondeterministic float operations
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
What it does
This restriction lint would detect calls to standard library floating-point functions whose definitions are platform-dependent or nondeterministic, such as f64::sin and f64::powf. It would not lint floating-point operations which are specified to be deterministic and precise, such as addition, f64::sqrt, and f64::round.
It would also lint f64::to_bits since, even though that operation is itself platform-independent, it can reveal architecture-dependent variation in the bits of NaNs produced by operations such as 1.0 / 0.0.
Advantage
One of the subtle things about floating-point arithmetic is that some operations — in particular, the basic arithmetic operators + - * / — are defined such that (on conformant platforms) they always produce identical results (except for the bits of NaNs), while other operations, such as sin(), are not. Not only that, Rust std implements many of the latter by calling out to the operating system's math library, so results may vary with platform.
For some portions of some applications (definitely not all!), it is useful to have a guarantee that, if the output of a particular call to a function fn(f32, f32, ...) -> f32 (which is defined in that application) is not NaN, then it is completely identical to the outputs of other calls with the same inputs. This lint would allow authors and maintainers of such code to avoid accidentally introducing nondeterminism or platform dependence.
It would also help people interested in the details of floating-point arithmetic learn about this distinction by telling them if they make a mistake while practicing writing deterministic code.
Drawbacks
- Another lint to maintain, for a relatively narrow purpose. Particularly, it needs to be kept up to date with the set of all floating point functions in
std, or it would have false negatives. - Some would claim that any use or expectation whatsoever of exact floating point values is foolish, and this lint supports that foolishness. I disagree; there are many useful things which this position rules out for no reason other than it being simpler to throw everything in the nondeterministic bucket. In any case, this lint is for people who want to take a more nuanced position than that, and have machine assistance with getting it right.
- It will not be able to detect nondeterminism resulting from calls to functions from third-party libraries, only
std.
Example
assert_eq!(0.1234567890123456789_f64.powi(2), 0.015241578753238836);
// ^^^^ use of nondeterministic function `powf`
assert_eq!(1234_f64.cos(), -0.7985506235875843);
// ^^^ use of nondeterministic function `cos`
Could be written as:
let x = 0.1234567890123456789_f64;
assert_eq!(x * x, 0.015241578753238836);
assert_eq!(libm::cos(1234_f64), -0.7985506235875843);
The above code sample is only for illustration of linted and lint-free code; I do not intend to ask that the lint make these particular suggestions.
(Also, libm doesn't offer any specific guarantees, so it should not be recommended. But in practice, it is at least plain Rust code that doesn’t use any nondeterministic ops in the current version, so the same version of the library will produce identical results, and the code could be vendored if necessary in the future.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue does not identify implementation files or tests. Start by surveying existing Clippy restriction lints and the Rust standard-library floating-point methods named in the examples; done means the lint covers the intended platform-dependent or nondeterministic operations while excluding deterministic operations such as addition, sqrt, and round.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100