about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYoshitomo Nakanishi <yurayura.rounin.3@gmail.com>2021-02-04 22:57:03 +0900
committerYoshitomo Nakanishi <yurayura.rounin.3@gmail.com>2021-02-04 22:57:03 +0900
commit8b8b0a94b05f7189d028d91deda659ed266ef09d (patch)
tree1d7d1e44d5bb36993b848844ad9aeb5211a344cd
parente32e4dedf1781a4696c34f31d69e68c7c0eaf6a9 (diff)
downloadrust-8b8b0a94b05f7189d028d91deda659ed266ef09d.tar.gz
rust-8b8b0a94b05f7189d028d91deda659ed266ef09d.zip
Fix enclosing_body_owner_opt and rename it to enclosing_body_opt
-rw-r--r--clippy_lints/src/default_numeric_fallback.rs47
1 files changed, 31 insertions, 16 deletions
diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs
index f049e64d0fb..5f0ee1be2b9 100644
--- a/clippy_lints/src/default_numeric_fallback.rs
+++ b/clippy_lints/src/default_numeric_fallback.rs
@@ -2,7 +2,7 @@ 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, Expr, ExprKind, FnDecl, FnRetTy, Guard, HirId, Lit, Stmt, StmtKind,
+    Body, BodyId, Expr, ExprKind, FnDecl, FnRetTy, Guard, HirId, Lit, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::{
@@ -50,16 +50,31 @@ declare_clippy_lint! {
 
 declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]);
 
-fn enclosing_body_owner_opt(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<HirId> {
+/// Return the body that includes passed `hir_id` if exists.
+fn enclosing_body_opt(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<BodyId> {
     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) {
-            return Some(hir_map.body_owner(body));
+            if trace.iter().any(|hir_id| *hir_id == body.hir_id) {
+                return Some(body);
+            }
         }
     }
+
     None
 }
 
+fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Option<Ty<'tcx>> {
+    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 LateLintPass<'_> for DefaultNumericFallback {
     fn check_fn(
         &mut self,
@@ -68,21 +83,17 @@ impl LateLintPass<'_> for DefaultNumericFallback {
         fn_decl: &'tcx FnDecl<'_>,
         body: &'tcx Body<'_>,
         _: Span,
-        hir_id: HirId,
+        _: HirId,
     ) {
         let ret_ty_bound = match fn_decl.output {
             FnRetTy::DefaultReturn(_) => None,
             FnRetTy::Return(ty) => Some(ty),
         }
         .and_then(|ty| {
-            let mut infer_ty_finder = InferTyFinder::new();
-            infer_ty_finder.visit_ty(ty);
-            if infer_ty_finder.found {
+            if is_infer_included(ty) {
                 None
-            } else if enclosing_body_owner_opt(cx.tcx, hir_id).is_some() {
-                cx.typeck_results().node_type_opt(ty.hir_id)
             } else {
-                Some(hir_ty_to_ty(cx.tcx, ty))
+                ty_from_hir_ty(cx, ty)
             }
         });
 
@@ -114,7 +125,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
         }
     }
 
-    /// Check whether lit cause fallback or not.
+    /// Check whether a passed literal has potential to cause fallback or not.
     fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>) {
         let ty_bound = self.ty_bounds.last().unwrap();
 
@@ -334,12 +345,10 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
         match stmt.kind {
             StmtKind::Local(local) => {
                 let ty = local.ty.and_then(|hir_ty| {
-                    let mut infer_ty_finder = InferTyFinder::new();
-                    infer_ty_finder.visit_ty(hir_ty);
-                    if infer_ty_finder.found {
+                    if is_infer_included(hir_ty) {
                         None
                     } else {
-                        self.cx.typeck_results().node_type_opt(hir_ty.hir_id)
+                        ty_from_hir_ty(self.cx, hir_ty)
                     }
                 });
                 self.ty_bounds.push(ty);
@@ -357,7 +366,13 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
     }
 }
 
-/// Find `hir::TyKind::Infer` is included in passed typed.
+/// Return true if a given ty includes `hir::TyKind::Infer`.
+fn is_infer_included(ty: &hir::Ty<'_>) -> bool {
+    let mut infer_ty_finder = InferTyFinder::new();
+    infer_ty_finder.visit_ty(ty);
+    infer_ty_finder.found
+}
+
 struct InferTyFinder {
     found: bool,
 }