diff --git a/clippy_lints/src/methods/unwrap_or_else_default.rs b/clippy_lints/src/methods/unwrap_or_else_default.rs index 14185503092..e641b5c4599 100644 --- a/clippy_lints/src/methods/unwrap_or_else_default.rs +++ b/clippy_lints/src/methods/unwrap_or_else_default.rs @@ -2,8 +2,8 @@ use super::UNWRAP_OR_ELSE_DEFAULT; use clippy_utils::{ - diagnostics::span_lint_and_sugg, is_default_equivalent_ctor, is_diag_trait_item, is_trait_item, - source::snippet_with_applicability, ty::is_type_diagnostic_item, + diagnostics::span_lint_and_sugg, is_default_equivalent_call, is_trait_item, source::snippet_with_applicability, + ty::is_type_diagnostic_item, }; use rustc_errors::Applicability; use rustc_hir as hir; @@ -23,21 +23,9 @@ pub(super) fn check<'tcx>( let is_option = is_type_diagnostic_item(cx, recv_ty, sym::Option); let is_result = is_type_diagnostic_item(cx, recv_ty, sym::Result); - let is_default_eq = match &u_arg.kind { - hir::ExprKind::Path(qpath) => { - if let Some(repl_def_id) = cx.qpath_res(qpath, u_arg.hir_id).opt_def_id() { - is_diag_trait_item(cx, repl_def_id, sym::Default) - || is_default_equivalent_ctor(cx, repl_def_id, qpath) - } else { - false - } - }, - _ => false, - }; - if_chain! { if is_option || is_result; - if is_trait_item(cx, u_arg, sym::Default) || is_default_eq; + if is_trait_item(cx, u_arg, sym::Default) || is_default_equivalent_call(cx, u_arg); then { let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 1b56bfbe1d6..4af870d3155 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -637,7 +637,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) - /// Returns true if the `def_id` associated with the `path` is recognized as a "default-equivalent" /// constructor from the std library -pub fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool { +fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool { let std_types_symbols = &[ sym::String, sym::Vec, @@ -664,6 +664,22 @@ pub fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QP false } +/// Return true if the expr is equal to `Default::default` when evaluated. +pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool { + if_chain! { + if let hir::ExprKind::Path(ref repl_func_qpath) = repl_func.kind; + if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); + if is_diag_trait_item(cx, repl_def_id, sym::Default) + || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath); + then { + true + } + else { + false + } + } +} + /// Returns true if the expr is equal to `Default::default()` of it's type when evaluated. /// It doesn't cover all cases, for example indirect function calls (some of std /// functions are supported) but it is the best we have. @@ -686,18 +702,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { false } }, - ExprKind::Call(repl_func, _) => if_chain! { - if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); - if is_diag_trait_item(cx, repl_def_id, sym::Default) - || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath); - then { - true - } - else { - false - } - }, + ExprKind::Call(repl_func, _) => is_default_equivalent_call(cx, repl_func), ExprKind::Path(qpath) => is_lang_ctor(cx, qpath, OptionNone), ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])), _ => false,