This commit is contained in:
Piotr Mikulski
2021-12-23 22:00:14 -08:00
parent 4b3a87f886
commit 01b7411482
2 changed files with 21 additions and 28 deletions

View File

@@ -2,8 +2,8 @@
use super::UNWRAP_OR_ELSE_DEFAULT; use super::UNWRAP_OR_ELSE_DEFAULT;
use clippy_utils::{ use clippy_utils::{
diagnostics::span_lint_and_sugg, is_default_equivalent_ctor, is_diag_trait_item, is_trait_item, diagnostics::span_lint_and_sugg, is_default_equivalent_call, is_trait_item, source::snippet_with_applicability,
source::snippet_with_applicability, ty::is_type_diagnostic_item, ty::is_type_diagnostic_item,
}; };
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; 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_option = is_type_diagnostic_item(cx, recv_ty, sym::Option);
let is_result = is_type_diagnostic_item(cx, recv_ty, sym::Result); 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_chain! {
if is_option || is_result; 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 { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;

View File

@@ -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" /// Returns true if the `def_id` associated with the `path` is recognized as a "default-equivalent"
/// constructor from the std library /// 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 = &[ let std_types_symbols = &[
sym::String, sym::String,
sym::Vec, sym::Vec,
@@ -664,6 +664,22 @@ pub fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QP
false 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. /// 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 /// It doesn't cover all cases, for example indirect function calls (some of std
/// functions are supported) but it is the best we have. /// 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 false
} }
}, },
ExprKind::Call(repl_func, _) => if_chain! { ExprKind::Call(repl_func, _) => is_default_equivalent_call(cx, repl_func),
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::Path(qpath) => is_lang_ctor(cx, qpath, OptionNone), ExprKind::Path(qpath) => is_lang_ctor(cx, qpath, OptionNone),
ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])), ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])),
_ => false, _ => false,