From bd583d91a1bf3717f724a38531e142aa4a9ee6cc Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 6 Jan 2022 12:41:17 -0600 Subject: [PATCH] Factor out is_qpath_def_path --- clippy_lints/src/infinite_iter.rs | 12 ++-- clippy_lints/src/matches.rs | 62 +++++++++++-------- .../methods/manual_saturating_arithmetic.rs | 8 +-- clippy_utils/src/lib.rs | 10 +-- 4 files changed, 44 insertions(+), 48 deletions(-) diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index 3008e86ef8b29..b6badef02f58a 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; -use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths}; +use clippy_utils::{get_trait_def_id, higher, match_def_path, path_def_id, paths}; use rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -167,13 +167,9 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { }, ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)), ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e), - ExprKind::Call(path, _) => { - if let ExprKind::Path(ref qpath) = path.kind { - is_qpath_def_path(cx, qpath, path.hir_id, &paths::ITER_REPEAT).into() - } else { - Finite - } - }, + ExprKind::Call(path, _) => path_def_id(cx, path) + .map_or(false, |id| match_def_path(cx, id, &paths::ITER_REPEAT)) + .into(), ExprKind::Struct(..) => higher::Range::hir(expr).map_or(false, |r| r.end.is_none()).into(), _ => Finite, } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 2579404fb18cc..81ae4dacdf615 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1765,22 +1765,22 @@ where mod redundant_pattern_match { use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_then; - use clippy_utils::higher; use clippy_utils::source::snippet; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, is_type_lang_item, match_type}; - use clippy_utils::{is_lang_ctor, is_qpath_def_path, is_trait_method, paths}; + use clippy_utils::{higher, match_def_path}; + use clippy_utils::{is_lang_ctor, is_trait_method, paths}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; - use rustc_hir::LangItem::{OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk}; + use rustc_hir::LangItem::{OptionNone, PollPending}; use rustc_hir::{ intravisit::{walk_expr, Visitor}, Arm, Block, Expr, ExprKind, LangItem, MatchSource, Node, Pat, PatKind, QPath, UnOp, }; use rustc_lint::LateContext; - use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; + use rustc_middle::ty::{self, subst::GenericArgKind, DefIdTree, Ty}; use rustc_span::sym; pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { @@ -1956,28 +1956,31 @@ mod redundant_pattern_match { has_else: bool, ) { // also look inside refs - let mut kind = &let_pat.kind; // if we have &None for example, peel it so we can detect "if let None = x" - if let PatKind::Ref(inner, _mutability) = kind { - kind = &inner.kind; - } + let check_pat = match let_pat.kind { + PatKind::Ref(inner, _mutability) => inner, + _ => let_pat, + }; let op_ty = cx.typeck_results().expr_ty(let_expr); // Determine which function should be used, and the type contained by the corresponding // variant. - let (good_method, inner_ty) = match kind { - PatKind::TupleStruct(ref path, [sub_pat], _) => { + let (good_method, inner_ty) = match check_pat.kind { + PatKind::TupleStruct(ref qpath, [sub_pat], _) => { if let PatKind::Wild = sub_pat.kind { - if is_lang_ctor(cx, path, ResultOk) { + let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id); + let Some(id) = res.opt_def_id().and_then(|ctor_id| cx.tcx.parent(ctor_id)) else { return }; + let lang_items = cx.tcx.lang_items(); + if Some(id) == lang_items.result_ok_variant() { ("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty)) - } else if is_lang_ctor(cx, path, ResultErr) { + } else if Some(id) == lang_items.result_err_variant() { ("is_err()", try_get_generic_ty(op_ty, 1).unwrap_or(op_ty)) - } else if is_lang_ctor(cx, path, OptionSome) { + } else if Some(id) == lang_items.option_some_variant() { ("is_some()", op_ty) - } else if is_lang_ctor(cx, path, PollReady) { + } else if Some(id) == lang_items.poll_ready_variant() { ("is_ready()", op_ty) - } else if is_qpath_def_path(cx, path, sub_pat.hir_id, &paths::IPADDR_V4) { + } else if match_def_path(cx, id, &paths::IPADDR_V4) { ("is_ipv4()", op_ty) - } else if is_qpath_def_path(cx, path, sub_pat.hir_id, &paths::IPADDR_V6) { + } else if match_def_path(cx, id, &paths::IPADDR_V6) { ("is_ipv6()", op_ty) } else { return; @@ -2177,17 +2180,22 @@ mod redundant_pattern_match { should_be_left: &'a str, should_be_right: &'a str, ) -> Option<&'a str> { - let body_node_pair = if is_qpath_def_path(cx, path_left, arms[0].pat.hir_id, expected_left) - && is_qpath_def_path(cx, path_right, arms[1].pat.hir_id, expected_right) - { - (&(*arms[0].body).kind, &(*arms[1].body).kind) - } else if is_qpath_def_path(cx, path_right, arms[1].pat.hir_id, expected_left) - && is_qpath_def_path(cx, path_left, arms[0].pat.hir_id, expected_right) - { - (&(*arms[1].body).kind, &(*arms[0].body).kind) - } else { - return None; - }; + let left_id = cx + .typeck_results() + .qpath_res(path_left, arms[0].pat.hir_id) + .opt_def_id()?; + let right_id = cx + .typeck_results() + .qpath_res(path_right, arms[1].pat.hir_id) + .opt_def_id()?; + let body_node_pair = + if match_def_path(cx, left_id, expected_left) && match_def_path(cx, right_id, expected_right) { + (&(*arms[0].body).kind, &(*arms[1].body).kind) + } else if match_def_path(cx, right_id, expected_left) && match_def_path(cx, right_id, expected_right) { + (&(*arms[1].body).kind, &(*arms[0].body).kind) + } else { + return None; + }; match body_node_pair { (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) { diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 4307cbf00507a..0fe510beaa07e 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::is_qpath_def_path; use clippy_utils::source::snippet_with_applicability; +use clippy_utils::{match_def_path, path_def_id}; use if_chain::if_chain; use rustc_ast::ast; use rustc_errors::Applicability; @@ -93,12 +93,12 @@ fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option, segments: &[&str]) -> bool { } } -/// Resolves the path to a `DefId` and checks if it matches the given path. -pub fn is_qpath_def_path(cx: &LateContext<'_>, path: &QPath<'_>, hir_id: HirId, segments: &[&str]) -> bool { - cx.qpath_res(path, hir_id) - .opt_def_id() - .map_or(false, |id| match_def_path(cx, id, segments)) -} - /// If the expression is a path, resolves it to a `DefId` and checks if it matches the given path. /// /// Please use `is_expr_diagnostic_item` if the target is a diagnostic item. @@ -1775,8 +1768,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool match expr.kind { ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)), - ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY), - _ => false, + _ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)), } }