Open astra90x opened 2 months ago
I also experimented with this idea a while ago but then got busy.
The two options I was thinking of was adding some kind of Vec<Expr>
to TypeckResults
for integer literal exprs at which fallback occurred so in clippy we can just go through it and emit a lint without needing any inference logic, or just uplifting it to rustc (which I think makes more sense, because we wouldn't need to add unnecessary things to the compiler that are only ever used by clippy, but maybe it's fine).
I think the simplest thing for now would be to add it onto TypeckResults
and use clippy. AFAICT there's plenty of things inside rustc that's currently used only by clippy, and if we do ever uplift this into rustc (which I'm not sure how well it would fit), it might work pretty similarly anyway.
What I'm uncertain about though is what exactly to add onto TypeckResults
. The way integer fallback works seems to be that during inference, it scans for all inferred numeric type "variables" which are unresolved, and at that point I don't see an easy way to find the span of the literal which created this type variable.
The two options which I can think of are to either walk the function body to scan for literals with types matching this type variable, or to track the span of these type variables like regular type variables. The first option doesn't seem clean to me, but the second option requires even more refactoring.
Summary
There are a number of cases where the lint
default_numeric_fallback
is emitted, but no numeric fallback actually occurs due to type inference. I want to use this lint on my projects, but it causes far too many false positives.Currently, the lint is emitted whenever a numeric literal contains no type suffix, is of the type
i32
orf64
, and is not a part of a large set of hardcoded cases where type inferences in known to occur. I believe that due to the complexity of type inference in Rust, the lint should instead directly check ifrustc
is actually doing numeric fallback.I would like to help work on a PR implementing these changes, but the private
rustc
crates currently don't seem to provide any sort of interface to check if numeric fallback occurred. I think the ideal implementation should hook into this function and I could think of a few approaches, but I'm not sure what's best. This would also require updatingrustc
and thenclippy
, and I'm unsure what the process for that is like.Furthermore, in my opinion, looking at RFC0212 as mentioned in the lint description, there are still a few common cases where the type fallen back to does not matter at all, and I think it's worth whitelisting those specific cases.
(0..100).map(|_| {})
: This include all cases where a range in used as an iterator, but all values out of the iterator is discarded. This is often used to iterate a set number of times, where the type doesn't matter.number << 8
: While fallback does occur here,<<
and>>
are implemented on all integer types with identical behavior.10 > 0
within a macro: I only include this because it was mentioned here. I have not yet ran into this case in my code.Lint Name
default_numeric_fallback
Reproducer
I tried this code:
I saw this happen: There is a warning on every single unsuffixed numeric literal.
I expected to see this happen: There should be no warning at all.
Version
Additional Labels
No response