]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/manual_unwrap_or.rs
Fix a `manual_unwrap_or` FP with deref coercion
[rust.git] / clippy_lints / src / manual_unwrap_or.rs
index 65baa2552ccc6b7758b9ce9c7570beb914539368..cf183d4c16f12a505143bc055e9136a1d0424feb 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_lint::LintContext;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::adjustment::Adjust;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 
@@ -87,6 +88,8 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&'
             if let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind;
             if path_to_local_id(unwrap_arm.body, binding_hir_id);
             if !contains_return_break_continue_macro(or_arm.body);
+            if !cx.typeck_results().expr_adjustments(unwrap_arm.body).iter()
+                .any(|a| matches!(a.kind, Adjust::Deref(Some(..))));
             then {
                 Some(or_arm)
             } else {
@@ -112,6 +115,15 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&'
         then {
             let reindented_or_body =
                 reindent_multiline(or_body_snippet.into(), true, Some(indent));
+
+            let suggestion = if scrutinee.span.from_expansion() {
+                    // we don't want parenthesis around macro, e.g. `(some_macro!()).unwrap_or(0)`
+                    sugg::Sugg::hir_with_macro_callsite(cx, scrutinee, "..")
+                }
+                else {
+                    sugg::Sugg::hir(cx, scrutinee, "..").maybe_par()
+                };
+
             span_lint_and_sugg(
                 cx,
                 MANUAL_UNWRAP_OR, expr.span,
@@ -119,7 +131,7 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&'
                 "replace with",
                 format!(
                     "{}.unwrap_or({})",
-                    sugg::Sugg::hir(cx, scrutinee, "..").maybe_par(),
+                    suggestion,
                     reindented_or_body,
                 ),
                 Applicability::MachineApplicable,