Auto merge of #7446 - Y-Nak:fix-7445, r=xFrednet,flip1995
`default_numeric_fallback`: Fix FP with floating literal Fix #7445 changelog: `default_numeric_fallback`: Fix FP with floating literal
This commit is contained in:
commit
8131445e53
@ -1,5 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::numeric_literal;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
@ -78,16 +79,25 @@ fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>) {
|
||||
if let Some(ty_bound) = self.ty_bounds.last();
|
||||
if matches!(lit.node,
|
||||
LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed));
|
||||
if !ty_bound.is_integral();
|
||||
if !ty_bound.is_numeric();
|
||||
then {
|
||||
let suffix = match lit_ty.kind() {
|
||||
ty::Int(IntTy::I32) => "i32",
|
||||
ty::Float(FloatTy::F64) => "f64",
|
||||
let (suffix, is_float) = match lit_ty.kind() {
|
||||
ty::Int(IntTy::I32) => ("i32", false),
|
||||
ty::Float(FloatTy::F64) => ("f64", true),
|
||||
// Default numeric fallback never results in other types.
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let sugg = format!("{}_{}", snippet(self.cx, lit.span, ""), suffix);
|
||||
let src = if let Some(src) = snippet_opt(self.cx, lit.span) {
|
||||
src
|
||||
} else {
|
||||
match lit.node {
|
||||
LitKind::Int(src, _) => format!("{}", src),
|
||||
LitKind::Float(src, _) => format!("{}", src),
|
||||
_ => return,
|
||||
}
|
||||
};
|
||||
let sugg = numeric_literal::format(&src, Some(suffix), is_float);
|
||||
span_lint_and_sugg(
|
||||
self.cx,
|
||||
DEFAULT_NUMERIC_FALLBACK,
|
||||
@ -219,10 +229,10 @@ enum TyBound<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TyBound<'tcx> {
|
||||
fn is_integral(self) -> bool {
|
||||
fn is_numeric(self) -> bool {
|
||||
match self {
|
||||
TyBound::Any => true,
|
||||
TyBound::Ty(t) => t.is_integral(),
|
||||
TyBound::Ty(t) => t.is_numeric(),
|
||||
TyBound::Nothing => false,
|
||||
}
|
||||
}
|
||||
|
@ -162,6 +162,9 @@ pub fn format(&self) -> String {
|
||||
}
|
||||
|
||||
if let Some(suffix) = self.suffix {
|
||||
if output.ends_with('.') {
|
||||
output.push('0');
|
||||
}
|
||||
output.push('_');
|
||||
output.push_str(suffix);
|
||||
}
|
||||
|
174
tests/ui/default_numeric_fallback_f64.fixed
Normal file
174
tests/ui/default_numeric_fallback_f64.fixed
Normal file
@ -0,0 +1,174 @@
|
||||
// run-rustfix
|
||||
// aux-build:macro_rules.rs
|
||||
|
||||
#![warn(clippy::default_numeric_fallback)]
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::never_loop)]
|
||||
#![allow(clippy::no_effect)]
|
||||
#![allow(clippy::unnecessary_operation)]
|
||||
#![allow(clippy::branches_sharing_code)]
|
||||
#![allow(clippy::match_single_binding)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate macro_rules;
|
||||
|
||||
mod basic_expr {
|
||||
fn test() {
|
||||
// Should lint unsuffixed literals typed `f64`.
|
||||
let x = 0.12_f64;
|
||||
let x = [1.0_f64, 2.0_f64, 3.0_f64];
|
||||
let x = if true { (1.0_f64, 2.0_f64) } else { (3.0_f64, 4.0_f64) };
|
||||
let x = match 1.0_f64 {
|
||||
_ => 1.0_f64,
|
||||
};
|
||||
|
||||
// Should NOT lint suffixed literals.
|
||||
let x = 0.12_f64;
|
||||
|
||||
// Should NOT lint literals in init expr if `Local` has a type annotation.
|
||||
let x: f64 = 0.1;
|
||||
let x: [f64; 3] = [1., 2., 3.];
|
||||
let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };
|
||||
let x: _ = 1.;
|
||||
}
|
||||
}
|
||||
|
||||
mod nested_local {
|
||||
fn test() {
|
||||
let x: _ = {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1.0_f64;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
1.
|
||||
};
|
||||
|
||||
let x: _ = if true {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1.0_f64;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
1.
|
||||
} else {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1.0_f64;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
2.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mod function_def {
|
||||
fn ret_f64() -> f64 {
|
||||
// Even though the output type is specified,
|
||||
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
|
||||
1.0_f64
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should lint this because return type is inferred to `f64` and NOT bound to a concrete
|
||||
// type.
|
||||
let f = || -> _ { 1.0_f64 };
|
||||
|
||||
// Even though the output type is specified,
|
||||
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
|
||||
let f = || -> f64 { 1.0_f64 };
|
||||
}
|
||||
}
|
||||
|
||||
mod function_calls {
|
||||
fn concrete_arg(f: f64) {}
|
||||
|
||||
fn generic_arg<T>(t: T) {}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the argument type is bound to a concrete type.
|
||||
concrete_arg(1.);
|
||||
|
||||
// Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
|
||||
generic_arg(1.0_f64);
|
||||
|
||||
// Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
|
||||
let x: _ = generic_arg(1.0_f64);
|
||||
}
|
||||
}
|
||||
|
||||
mod struct_ctor {
|
||||
struct ConcreteStruct {
|
||||
x: f64,
|
||||
}
|
||||
|
||||
struct GenericStruct<T> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteStruct { x: 1. };
|
||||
|
||||
// Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
|
||||
GenericStruct { x: 1.0_f64 };
|
||||
|
||||
// Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
|
||||
let _ = GenericStruct { x: 1.0_f64 };
|
||||
}
|
||||
}
|
||||
|
||||
mod enum_ctor {
|
||||
enum ConcreteEnum {
|
||||
X(f64),
|
||||
}
|
||||
|
||||
enum GenericEnum<T> {
|
||||
X(T),
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteEnum::X(1.);
|
||||
|
||||
// Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
|
||||
GenericEnum::X(1.0_f64);
|
||||
}
|
||||
}
|
||||
|
||||
mod method_calls {
|
||||
struct StructForMethodCallTest {}
|
||||
|
||||
impl StructForMethodCallTest {
|
||||
fn concrete_arg(&self, f: f64) {}
|
||||
|
||||
fn generic_arg<T>(&self, t: T) {}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let s = StructForMethodCallTest {};
|
||||
|
||||
// Should NOT lint this because the argument type is bound to a concrete type.
|
||||
s.concrete_arg(1.);
|
||||
|
||||
// Should lint this because the argument type is bound to a concrete type.
|
||||
s.generic_arg(1.0_f64);
|
||||
}
|
||||
}
|
||||
|
||||
mod in_macro {
|
||||
macro_rules! internal_macro {
|
||||
() => {
|
||||
let x = 22.0_f64;
|
||||
};
|
||||
}
|
||||
|
||||
// Should lint in internal macro.
|
||||
fn internal() {
|
||||
internal_macro!();
|
||||
}
|
||||
|
||||
// Should NOT lint in external macro.
|
||||
fn external() {
|
||||
default_numeric_fallback!();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
174
tests/ui/default_numeric_fallback_f64.rs
Normal file
174
tests/ui/default_numeric_fallback_f64.rs
Normal file
@ -0,0 +1,174 @@
|
||||
// run-rustfix
|
||||
// aux-build:macro_rules.rs
|
||||
|
||||
#![warn(clippy::default_numeric_fallback)]
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::never_loop)]
|
||||
#![allow(clippy::no_effect)]
|
||||
#![allow(clippy::unnecessary_operation)]
|
||||
#![allow(clippy::branches_sharing_code)]
|
||||
#![allow(clippy::match_single_binding)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate macro_rules;
|
||||
|
||||
mod basic_expr {
|
||||
fn test() {
|
||||
// Should lint unsuffixed literals typed `f64`.
|
||||
let x = 0.12;
|
||||
let x = [1., 2., 3.];
|
||||
let x = if true { (1., 2.) } else { (3., 4.) };
|
||||
let x = match 1. {
|
||||
_ => 1.,
|
||||
};
|
||||
|
||||
// Should NOT lint suffixed literals.
|
||||
let x = 0.12_f64;
|
||||
|
||||
// Should NOT lint literals in init expr if `Local` has a type annotation.
|
||||
let x: f64 = 0.1;
|
||||
let x: [f64; 3] = [1., 2., 3.];
|
||||
let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };
|
||||
let x: _ = 1.;
|
||||
}
|
||||
}
|
||||
|
||||
mod nested_local {
|
||||
fn test() {
|
||||
let x: _ = {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1.;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
1.
|
||||
};
|
||||
|
||||
let x: _ = if true {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1.;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
1.
|
||||
} else {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1.;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
2.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mod function_def {
|
||||
fn ret_f64() -> f64 {
|
||||
// Even though the output type is specified,
|
||||
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
|
||||
1.
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should lint this because return type is inferred to `f64` and NOT bound to a concrete
|
||||
// type.
|
||||
let f = || -> _ { 1. };
|
||||
|
||||
// Even though the output type is specified,
|
||||
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
|
||||
let f = || -> f64 { 1. };
|
||||
}
|
||||
}
|
||||
|
||||
mod function_calls {
|
||||
fn concrete_arg(f: f64) {}
|
||||
|
||||
fn generic_arg<T>(t: T) {}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the argument type is bound to a concrete type.
|
||||
concrete_arg(1.);
|
||||
|
||||
// Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
|
||||
generic_arg(1.);
|
||||
|
||||
// Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
|
||||
let x: _ = generic_arg(1.);
|
||||
}
|
||||
}
|
||||
|
||||
mod struct_ctor {
|
||||
struct ConcreteStruct {
|
||||
x: f64,
|
||||
}
|
||||
|
||||
struct GenericStruct<T> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteStruct { x: 1. };
|
||||
|
||||
// Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
|
||||
GenericStruct { x: 1. };
|
||||
|
||||
// Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
|
||||
let _ = GenericStruct { x: 1. };
|
||||
}
|
||||
}
|
||||
|
||||
mod enum_ctor {
|
||||
enum ConcreteEnum {
|
||||
X(f64),
|
||||
}
|
||||
|
||||
enum GenericEnum<T> {
|
||||
X(T),
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteEnum::X(1.);
|
||||
|
||||
// Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
|
||||
GenericEnum::X(1.);
|
||||
}
|
||||
}
|
||||
|
||||
mod method_calls {
|
||||
struct StructForMethodCallTest {}
|
||||
|
||||
impl StructForMethodCallTest {
|
||||
fn concrete_arg(&self, f: f64) {}
|
||||
|
||||
fn generic_arg<T>(&self, t: T) {}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let s = StructForMethodCallTest {};
|
||||
|
||||
// Should NOT lint this because the argument type is bound to a concrete type.
|
||||
s.concrete_arg(1.);
|
||||
|
||||
// Should lint this because the argument type is bound to a concrete type.
|
||||
s.generic_arg(1.);
|
||||
}
|
||||
}
|
||||
|
||||
mod in_macro {
|
||||
macro_rules! internal_macro {
|
||||
() => {
|
||||
let x = 22.;
|
||||
};
|
||||
}
|
||||
|
||||
// Should lint in internal macro.
|
||||
fn internal() {
|
||||
internal_macro!();
|
||||
}
|
||||
|
||||
// Should NOT lint in external macro.
|
||||
fn external() {
|
||||
default_numeric_fallback!();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
147
tests/ui/default_numeric_fallback_f64.stderr
Normal file
147
tests/ui/default_numeric_fallback_f64.stderr
Normal file
@ -0,0 +1,147 @@
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:18:17
|
||||
|
|
||||
LL | let x = 0.12;
|
||||
| ^^^^ help: consider adding suffix: `0.12_f64`
|
||||
|
|
||||
= note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:19:18
|
||||
|
|
||||
LL | let x = [1., 2., 3.];
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:19:22
|
||||
|
|
||||
LL | let x = [1., 2., 3.];
|
||||
| ^^ help: consider adding suffix: `2.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:19:26
|
||||
|
|
||||
LL | let x = [1., 2., 3.];
|
||||
| ^^ help: consider adding suffix: `3.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:20:28
|
||||
|
|
||||
LL | let x = if true { (1., 2.) } else { (3., 4.) };
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:20:32
|
||||
|
|
||||
LL | let x = if true { (1., 2.) } else { (3., 4.) };
|
||||
| ^^ help: consider adding suffix: `2.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:20:46
|
||||
|
|
||||
LL | let x = if true { (1., 2.) } else { (3., 4.) };
|
||||
| ^^ help: consider adding suffix: `3.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:20:50
|
||||
|
|
||||
LL | let x = if true { (1., 2.) } else { (3., 4.) };
|
||||
| ^^ help: consider adding suffix: `4.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:21:23
|
||||
|
|
||||
LL | let x = match 1. {
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:22:18
|
||||
|
|
||||
LL | _ => 1.,
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:40:21
|
||||
|
|
||||
LL | let y = 1.;
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:48:21
|
||||
|
|
||||
LL | let y = 1.;
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:54:21
|
||||
|
|
||||
LL | let y = 1.;
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:66:9
|
||||
|
|
||||
LL | 1.
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:72:27
|
||||
|
|
||||
LL | let f = || -> _ { 1. };
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:76:29
|
||||
|
|
||||
LL | let f = || -> f64 { 1. };
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:90:21
|
||||
|
|
||||
LL | generic_arg(1.);
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:93:32
|
||||
|
|
||||
LL | let x: _ = generic_arg(1.);
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:111:28
|
||||
|
|
||||
LL | GenericStruct { x: 1. };
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:114:36
|
||||
|
|
||||
LL | let _ = GenericStruct { x: 1. };
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:132:24
|
||||
|
|
||||
LL | GenericEnum::X(1.);
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:152:23
|
||||
|
|
||||
LL | s.generic_arg(1.);
|
||||
| ^^ help: consider adding suffix: `1.0_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_f64.rs:159:21
|
||||
|
|
||||
LL | let x = 22.;
|
||||
| ^^^ help: consider adding suffix: `22.0_f64`
|
||||
...
|
||||
LL | internal_macro!();
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 23 previous errors
|
||||
|
173
tests/ui/default_numeric_fallback_i32.fixed
Normal file
173
tests/ui/default_numeric_fallback_i32.fixed
Normal file
@ -0,0 +1,173 @@
|
||||
// run-rustfix
|
||||
// aux-build:macro_rules.rs
|
||||
|
||||
#![warn(clippy::default_numeric_fallback)]
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::never_loop)]
|
||||
#![allow(clippy::no_effect)]
|
||||
#![allow(clippy::unnecessary_operation)]
|
||||
#![allow(clippy::branches_sharing_code)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate macro_rules;
|
||||
|
||||
mod basic_expr {
|
||||
fn test() {
|
||||
// Should lint unsuffixed literals typed `i32`.
|
||||
let x = 22_i32;
|
||||
let x = [1_i32, 2_i32, 3_i32];
|
||||
let x = if true { (1_i32, 2_i32) } else { (3_i32, 4_i32) };
|
||||
let x = match 1_i32 {
|
||||
1_i32 => 1_i32,
|
||||
_ => 2_i32,
|
||||
};
|
||||
|
||||
// Should NOT lint suffixed literals.
|
||||
let x = 22_i32;
|
||||
|
||||
// Should NOT lint literals in init expr if `Local` has a type annotation.
|
||||
let x: [i32; 3] = [1, 2, 3];
|
||||
let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };
|
||||
let x: _ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
mod nested_local {
|
||||
fn test() {
|
||||
let x: _ = {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1_i32;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
1
|
||||
};
|
||||
|
||||
let x: _ = if true {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1_i32;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
1
|
||||
} else {
|
||||
// Should lint this because this literal is not bound to any types.
|
||||
let y = 1_i32;
|
||||
|
||||
// Should NOT lint this because this literal is bound to `_` of outer `Local`.
|
||||
2
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mod function_def {
|
||||
fn ret_i32() -> i32 {
|
||||
// Even though the output type is specified,
|
||||
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
|
||||
1_i32
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should lint this because return type is inferred to `i32` and NOT bound to a concrete
|
||||
// type.
|
||||
let f = || -> _ { 1_i32 };
|
||||
|
||||
// Even though the output type is specified,
|
||||
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
|
||||
let f = || -> i32 { 1_i32 };
|
||||
}
|
||||
}
|
||||
|
||||
mod function_calls {
|
||||
fn concrete_arg(x: i32) {}
|
||||
|
||||
fn generic_arg<T>(t: T) {}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the argument type is bound to a concrete type.
|
||||
concrete_arg(1);
|
||||
|
||||
// Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.
|
||||
generic_arg(1_i32);
|
||||
|
||||
// Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.
|
||||
let x: _ = generic_arg(1_i32);
|
||||
}
|
||||
}
|
||||
|
||||
mod struct_ctor {
|
||||
struct ConcreteStruct {
|
||||
x: i32,
|
||||
}
|
||||
|
||||
struct GenericStruct<T> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteStruct { x: 1 };
|
||||
|
||||
// Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
|
||||
GenericStruct { x: 1_i32 };
|
||||
|
||||
// Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
|
||||
let _ = GenericStruct { x: 1_i32 };
|
||||
}
|
||||
}
|
||||
|
||||
mod enum_ctor {
|
||||
enum ConcreteEnum {
|
||||
X(i32),
|
||||
}
|
||||
|
||||
enum GenericEnum<T> {
|
||||
X(T),
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteEnum::X(1);
|
||||
|
||||
// Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
|
||||
GenericEnum::X(1_i32);
|
||||
}
|
||||
}
|
||||
|
||||
mod method_calls {
|
||||
struct StructForMethodCallTest {}
|
||||
|
||||
impl StructForMethodCallTest {
|
||||
fn concrete_arg(&self, x: i32) {}
|
||||
|
||||
fn generic_arg<T>(&self, t: T) {}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let s = StructForMethodCallTest {};
|
||||
|
||||
// Should NOT lint this because the argument type is bound to a concrete type.
|
||||
s.concrete_arg(1);
|
||||
|
||||
// Should lint this because the argument type is bound to a concrete type.
|
||||
s.generic_arg(1_i32);
|
||||
}
|
||||
}
|
||||
|
||||
mod in_macro {
|
||||
macro_rules! internal_macro {
|
||||
() => {
|
||||
let x = 22_i32;
|
||||
};
|
||||
}
|
||||
|
||||
// Should lint in internal macro.
|
||||
fn internal() {
|
||||
internal_macro!();
|
||||
}
|
||||
|
||||
// Should NOT lint in external macro.
|
||||
fn external() {
|
||||
default_numeric_fallback!();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,3 +1,4 @@
|
||||
// run-rustfix
|
||||
// aux-build:macro_rules.rs
|
||||
|
||||
#![warn(clippy::default_numeric_fallback)]
|
||||
@ -21,15 +22,10 @@ fn test() {
|
||||
_ => 2,
|
||||
};
|
||||
|
||||
// Should lint unsuffixed literals typed `f64`.
|
||||
let x = 0.12;
|
||||
|
||||
// Should NOT lint suffixed literals.
|
||||
let x = 22_i32;
|
||||
let x = 0.12_f64;
|
||||
|
||||
// Should NOT lint literals in init expr if `Local` has a type annotation.
|
||||
let x: f64 = 0.1;
|
||||
let x: [i32; 3] = [1, 2, 3];
|
||||
let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };
|
||||
let x: _ = 1;
|
||||
@ -118,6 +114,24 @@ fn test() {
|
||||
}
|
||||
}
|
||||
|
||||
mod enum_ctor {
|
||||
enum ConcreteEnum {
|
||||
X(i32),
|
||||
}
|
||||
|
||||
enum GenericEnum<T> {
|
||||
X(T),
|
||||
}
|
||||
|
||||
fn test() {
|
||||
// Should NOT lint this because the field type is bound to a concrete type.
|
||||
ConcreteEnum::X(1);
|
||||
|
||||
// Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
|
||||
GenericEnum::X(1);
|
||||
}
|
||||
}
|
||||
|
||||
mod method_calls {
|
||||
struct StructForMethodCallTest {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:16:17
|
||||
--> $DIR/default_numeric_fallback_i32.rs:17:17
|
||||
|
|
||||
LL | let x = 22;
|
||||
| ^^ help: consider adding suffix: `22_i32`
|
||||
@ -7,145 +7,145 @@ LL | let x = 22;
|
||||
= note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:17:18
|
||||
--> $DIR/default_numeric_fallback_i32.rs:18:18
|
||||
|
|
||||
LL | let x = [1, 2, 3];
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:17:21
|
||||
--> $DIR/default_numeric_fallback_i32.rs:18:21
|
||||
|
|
||||
LL | let x = [1, 2, 3];
|
||||
| ^ help: consider adding suffix: `2_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:17:24
|
||||
--> $DIR/default_numeric_fallback_i32.rs:18:24
|
||||
|
|
||||
LL | let x = [1, 2, 3];
|
||||
| ^ help: consider adding suffix: `3_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:18:28
|
||||
--> $DIR/default_numeric_fallback_i32.rs:19:28
|
||||
|
|
||||
LL | let x = if true { (1, 2) } else { (3, 4) };
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:18:31
|
||||
--> $DIR/default_numeric_fallback_i32.rs:19:31
|
||||
|
|
||||
LL | let x = if true { (1, 2) } else { (3, 4) };
|
||||
| ^ help: consider adding suffix: `2_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:18:44
|
||||
--> $DIR/default_numeric_fallback_i32.rs:19:44
|
||||
|
|
||||
LL | let x = if true { (1, 2) } else { (3, 4) };
|
||||
| ^ help: consider adding suffix: `3_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:18:47
|
||||
--> $DIR/default_numeric_fallback_i32.rs:19:47
|
||||
|
|
||||
LL | let x = if true { (1, 2) } else { (3, 4) };
|
||||
| ^ help: consider adding suffix: `4_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:19:23
|
||||
--> $DIR/default_numeric_fallback_i32.rs:20:23
|
||||
|
|
||||
LL | let x = match 1 {
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:20:13
|
||||
--> $DIR/default_numeric_fallback_i32.rs:21:13
|
||||
|
|
||||
LL | 1 => 1,
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:20:18
|
||||
--> $DIR/default_numeric_fallback_i32.rs:21:18
|
||||
|
|
||||
LL | 1 => 1,
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:21:18
|
||||
--> $DIR/default_numeric_fallback_i32.rs:22:18
|
||||
|
|
||||
LL | _ => 2,
|
||||
| ^ help: consider adding suffix: `2_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:25:17
|
||||
|
|
||||
LL | let x = 0.12;
|
||||
| ^^^^ help: consider adding suffix: `0.12_f64`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:43:21
|
||||
--> $DIR/default_numeric_fallback_i32.rs:39:21
|
||||
|
|
||||
LL | let y = 1;
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:51:21
|
||||
--> $DIR/default_numeric_fallback_i32.rs:47:21
|
||||
|
|
||||
LL | let y = 1;
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:57:21
|
||||
--> $DIR/default_numeric_fallback_i32.rs:53:21
|
||||
|
|
||||
LL | let y = 1;
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:69:9
|
||||
--> $DIR/default_numeric_fallback_i32.rs:65:9
|
||||
|
|
||||
LL | 1
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:75:27
|
||||
--> $DIR/default_numeric_fallback_i32.rs:71:27
|
||||
|
|
||||
LL | let f = || -> _ { 1 };
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:79:29
|
||||
--> $DIR/default_numeric_fallback_i32.rs:75:29
|
||||
|
|
||||
LL | let f = || -> i32 { 1 };
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:93:21
|
||||
--> $DIR/default_numeric_fallback_i32.rs:89:21
|
||||
|
|
||||
LL | generic_arg(1);
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:96:32
|
||||
--> $DIR/default_numeric_fallback_i32.rs:92:32
|
||||
|
|
||||
LL | let x: _ = generic_arg(1);
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:114:28
|
||||
--> $DIR/default_numeric_fallback_i32.rs:110:28
|
||||
|
|
||||
LL | GenericStruct { x: 1 };
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:117:36
|
||||
--> $DIR/default_numeric_fallback_i32.rs:113:36
|
||||
|
|
||||
LL | let _ = GenericStruct { x: 1 };
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:137:23
|
||||
--> $DIR/default_numeric_fallback_i32.rs:131:24
|
||||
|
|
||||
LL | GenericEnum::X(1);
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback_i32.rs:151:23
|
||||
|
|
||||
LL | s.generic_arg(1);
|
||||
| ^ help: consider adding suffix: `1_i32`
|
||||
|
||||
error: default numeric fallback might occur
|
||||
--> $DIR/default_numeric_fallback.rs:144:21
|
||||
--> $DIR/default_numeric_fallback_i32.rs:158:21
|
||||
|
|
||||
LL | let x = 22;
|
||||
| ^^ help: consider adding suffix: `22_i32`
|
Loading…
Reference in New Issue
Block a user