Skip to content

Commit

Permalink
New lint: default_numeric_fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
Y-Nak committed Feb 2, 2021
1 parent c5f3f9d commit 547bc1b
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,7 @@ Released 2018-09-13
[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call
[`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation
[`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
[`default_numeric_fallback`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_numeric_fallback
[`default_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access
[`deprecated_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr
[`deprecated_semver`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_semver
Expand Down
62 changes: 62 additions & 0 deletions clippy_lints/src/default_numeric_fallback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};

use crate::utils::span_lint_and_help;

declare_clippy_lint! {
/// **What it does:** Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
/// inference.
///
/// Default numeric fallback means that if numeric types have not yet been bound to concrete
/// types at the end of type inference, then integer type is bound to `i32`, and similarly
/// floating type is bound to `f64`.
///
/// See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.
///
/// **Why is this bad?** For those who are very careful about types, default numeric fallback
/// may be a pitfall that cause unexpected runtime behavior.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let i = 10;
/// let f = 1.23;
/// ```
///
/// Use instead:
/// ```rust
/// let i = 10i32;
/// let f = 1.23f64;
/// ```
pub DEFAULT_NUMERIC_FALLBACK,
restriction,
"usage of unconstrained numeric literals which may cause default numeric fallback."
}

declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]);

impl LateLintPass<'_> for DefaultNumericFallback {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let lit = match &expr.kind {
ExprKind::Lit(lit) => lit,
_ => return,
};

match (&lit.node, cx.typeck_results().expr_ty(expr).kind()) {
(LitKind::Int(_, LitIntType::Unsuffixed), ty::Int(ty::IntTy::I32))
| (LitKind::Float(_, LitFloatType::Unsuffixed), ty::Float(ty::FloatTy::F64)) => span_lint_and_help(
cx,
DEFAULT_NUMERIC_FALLBACK,
lit.span,
"default numeric fallback may occured",
None,
"Consider adding suffix to avoid default numeric fallback",
),
_ => {},
}
}
}
4 changes: 4 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ mod copy_iterator;
mod create_dir;
mod dbg_macro;
mod default;
mod default_numeric_fallback;
mod dereference;
mod derive;
mod disallowed_method;
Expand Down Expand Up @@ -584,6 +585,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
&dbg_macro::DBG_MACRO,
&default::DEFAULT_TRAIT_ACCESS,
&default::FIELD_REASSIGN_WITH_DEFAULT,
&default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK,
&dereference::EXPLICIT_DEREF_METHODS,
&derive::DERIVE_HASH_XOR_EQ,
&derive::DERIVE_ORD_XOR_PARTIAL_ORD,
Expand Down Expand Up @@ -1025,6 +1027,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|| box strings::StringAdd);
store.register_late_pass(|| box implicit_return::ImplicitReturn);
store.register_late_pass(|| box implicit_saturating_sub::ImplicitSaturatingSub);
store.register_late_pass(|| box default_numeric_fallback::DefaultNumericFallback);

let msrv = conf.msrv.as_ref().and_then(|s| {
parse_msrv(s, None, None).or_else(|| {
Expand Down Expand Up @@ -1257,6 +1260,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
LintId::of(&create_dir::CREATE_DIR),
LintId::of(&dbg_macro::DBG_MACRO),
LintId::of(&default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK),
LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
LintId::of(&exhaustive_items::EXHAUSTIVE_ENUMS),
LintId::of(&exhaustive_items::EXHAUSTIVE_STRUCTS),
Expand Down
24 changes: 24 additions & 0 deletions tests/ui/default_numeric_fallback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![warn(clippy::default_numeric_fallback)]
#![allow(unused)]

fn foo_mono(x: u32) -> u32 {
x
}

fn foo_poly<T>(t: T) -> T {
t
}

fn main() {
let i = 23;
let f = 1.23;
foo_poly(10);
for _ in 0..10 {}

let x = 23i32;
let f = 1.23f64;
for i in 0..10 {
let _ = 10usize + i;
}
foo_mono(10);
}
43 changes: 43 additions & 0 deletions tests/ui/default_numeric_fallback.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error: default numeric fallback may occured
--> $DIR/default_numeric_fallback.rs:13:13
|
LL | let i = 23;
| ^^
|
= note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
= help: Consider adding suffix to avoid default numeric fallback

error: default numeric fallback may occured
--> $DIR/default_numeric_fallback.rs:14:13
|
LL | let f = 1.23;
| ^^^^
|
= help: Consider adding suffix to avoid default numeric fallback

error: default numeric fallback may occured
--> $DIR/default_numeric_fallback.rs:15:14
|
LL | foo_poly(10);
| ^^
|
= help: Consider adding suffix to avoid default numeric fallback

error: default numeric fallback may occured
--> $DIR/default_numeric_fallback.rs:16:14
|
LL | for _ in 0..10 {}
| ^
|
= help: Consider adding suffix to avoid default numeric fallback

error: default numeric fallback may occured
--> $DIR/default_numeric_fallback.rs:16:17
|
LL | for _ in 0..10 {}
| ^^
|
= help: Consider adding suffix to avoid default numeric fallback

error: aborting due to 5 previous errors

0 comments on commit 547bc1b

Please sign in to comment.