2021-08-12 04:16:25 -05:00
|
|
|
//! Lint for `some_result_or_option.unwrap_or_else(Default::default)`
|
|
|
|
|
|
|
|
use super::UNWRAP_OR_ELSE_DEFAULT;
|
|
|
|
use clippy_utils::{
|
2021-12-23 21:13:57 -06:00
|
|
|
diagnostics::span_lint_and_sugg, is_default_equivalent, is_trait_item, source::snippet_with_applicability,
|
|
|
|
ty::is_type_diagnostic_item,
|
2021-08-12 04:16:25 -05:00
|
|
|
};
|
|
|
|
use rustc_errors::Applicability;
|
|
|
|
use rustc_hir as hir;
|
|
|
|
use rustc_lint::LateContext;
|
|
|
|
use rustc_span::sym;
|
|
|
|
|
|
|
|
pub(super) fn check<'tcx>(
|
|
|
|
cx: &LateContext<'tcx>,
|
|
|
|
expr: &'tcx hir::Expr<'_>,
|
|
|
|
recv: &'tcx hir::Expr<'_>,
|
|
|
|
u_arg: &'tcx hir::Expr<'_>,
|
|
|
|
) {
|
|
|
|
// something.unwrap_or_else(Default::default)
|
|
|
|
// ^^^^^^^^^- recv ^^^^^^^^^^^^^^^^- u_arg
|
|
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- expr
|
|
|
|
let recv_ty = cx.typeck_results().expr_ty(recv);
|
2021-10-02 18:51:01 -05:00
|
|
|
let is_option = is_type_diagnostic_item(cx, recv_ty, sym::Option);
|
|
|
|
let is_result = is_type_diagnostic_item(cx, recv_ty, sym::Result);
|
2021-08-12 04:16:25 -05:00
|
|
|
|
|
|
|
if_chain! {
|
|
|
|
if is_option || is_result;
|
2021-12-23 21:13:57 -06:00
|
|
|
if is_trait_item(cx, u_arg, sym::Default) || is_default_equivalent(cx, u_arg);
|
2021-08-12 04:16:25 -05:00
|
|
|
then {
|
|
|
|
let mut applicability = Applicability::MachineApplicable;
|
|
|
|
|
|
|
|
span_lint_and_sugg(
|
|
|
|
cx,
|
|
|
|
UNWRAP_OR_ELSE_DEFAULT,
|
|
|
|
expr.span,
|
|
|
|
"use of `.unwrap_or_else(..)` to construct default value",
|
|
|
|
"try",
|
|
|
|
format!(
|
|
|
|
"{}.unwrap_or_default()",
|
|
|
|
snippet_with_applicability(cx, recv.span, "..", &mut applicability)
|
|
|
|
),
|
|
|
|
applicability,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|