From 22d4483dee55fbf0c9ba48a3ddfd8abe06805c07 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Sun, 7 Feb 2021 18:00:08 +0900 Subject: [PATCH] Simplify DefaultNumericFallback --- clippy_lints/src/default_numeric_fallback.rs | 394 ++----------------- clippy_lints/src/lib.rs | 2 +- tests/ui/default_numeric_fallback.rs | 101 +---- tests/ui/default_numeric_fallback.stderr | 176 +-------- 4 files changed, 61 insertions(+), 612 deletions(-) diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index 5f0ee1be2..b3b5a4a82 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -1,17 +1,9 @@ -use rustc_ast::ast::{Label, LitFloatType, LitIntType, LitKind}; -use rustc_hir::{ - self as hir, - intravisit::{walk_expr, walk_stmt, walk_ty, FnKind, NestedVisitorMap, Visitor}, - Body, BodyId, Expr, ExprKind, FnDecl, FnRetTy, Guard, HirId, Lit, Stmt, StmtKind, -}; +use rustc_ast::{LitFloatType, LitIntType, LitKind}; +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::{Expr, ExprKind, HirId, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::{ - hir::map::Map, - ty::{self, subst::GenericArgKind, FloatTy, IntTy, Ty, TyCtxt}, -}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::Span; -use rustc_typeck::hir_ty_to_ty; +use rustc_middle::ty::{self, FloatTy, IntTy}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use if_chain::if_chain; @@ -41,363 +33,53 @@ declare_clippy_lint! { /// Use instead: /// ```rust /// let i = 10i32; - /// let f = 1.23f64; + /// let f: f64 = 1.23; /// ``` pub DEFAULT_NUMERIC_FALLBACK, restriction, "usage of unconstrained numeric literals which may cause default numeric fallback." } -declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); - -/// Return the body that includes passed `hir_id` if exists. -fn enclosing_body_opt(tcx: TyCtxt<'_>, hir_id: HirId) -> Option { - let hir_map = tcx.hir(); - let mut trace = vec![(hir_id)]; - - for (parent, _) in hir_map.parent_iter(hir_id) { - trace.push(parent); - if let Some(body) = hir_map.maybe_body_owned_by(parent) { - if trace.iter().any(|hir_id| *hir_id == body.hir_id) { - return Some(body); - } - } - } - - None +#[derive(Default)] +pub struct DefaultNumericFallback { + /// Hold `init` in `Local` if `Local` has a type annotation. + bounded_inits: FxHashSet, } -fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Option> { - if enclosing_body_opt(cx.tcx, hir_ty.hir_id).is_some() { - cx.typeck_results().node_type_opt(hir_ty.hir_id) - } else { - Some(hir_ty_to_ty(cx.tcx, hir_ty)) - } -} +impl_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); impl LateLintPass<'_> for DefaultNumericFallback { - fn check_fn( - &mut self, - cx: &LateContext<'tcx>, - _: FnKind<'tcx>, - fn_decl: &'tcx FnDecl<'_>, - body: &'tcx Body<'_>, - _: Span, - _: HirId, - ) { - let ret_ty_bound = match fn_decl.output { - FnRetTy::DefaultReturn(_) => None, - FnRetTy::Return(ty) => Some(ty), - } - .and_then(|ty| { - if is_infer_included(ty) { - None - } else { - ty_from_hir_ty(cx, ty) + fn check_stmt(&mut self, _: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { + if_chain! { + if let StmtKind::Local(local) = stmt.kind; + if local.ty.is_some(); + if let Some(init) = local.init; + then { + self.bounded_inits.insert(init.hir_id); } - }); - - let mut visitor = NumericFallbackVisitor::new(ret_ty_bound, cx); - visitor.visit_body(body); - } -} - -struct NumericFallbackVisitor<'a, 'tcx> { - /// Stack manages type bound of exprs. The top element holds current expr type. - ty_bounds: Vec>>, - - /// Ret type bound. - ret_ty_bound: Option>, - - /// Break type bounds. - break_ty_bounds: Vec<(Option