From 44c62c9aa23e0d8401d9bdc1e2df913cfd035c7e Mon Sep 17 00:00:00 2001
From: Max Baumann <max@bmn.dev>
Date: Fri, 18 Mar 2022 00:51:26 +0100
Subject: [PATCH] feat: add tests and fix existing ones

---
 clippy_lints/src/use_unwrap_or.rs |  8 ++++----
 tests/ui/use_unwrap_or.rs         | 16 ++++++++++++++++
 tests/ui/use_unwrap_or.stderr     |  4 ++--
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/clippy_lints/src/use_unwrap_or.rs b/clippy_lints/src/use_unwrap_or.rs
index 8dc28231995..3e40014f50f 100644
--- a/clippy_lints/src/use_unwrap_or.rs
+++ b/clippy_lints/src/use_unwrap_or.rs
@@ -47,12 +47,12 @@ impl<'tcx> LateLintPass<'tcx> for UseUnwrapOr {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         // look for x.or().unwrap()
         if_chain! {
-            if let ExprKind::MethodCall(path, [unwrap_self], unwrap_span) = expr.kind;
+            if let ExprKind::MethodCall(path, [unwrap_self], unwrap_span) = &expr.kind;
             if path.ident.name == sym::unwrap;
-            if let ExprKind::MethodCall(caller_path, [or_self, or_arg], or_span) = unwrap_self.kind;
+            if let ExprKind::MethodCall(caller_path, [or_self, or_arg], or_span) = &unwrap_self.kind;
             if caller_path.ident.name == sym::or;
             then {
-                let ty = cx.typeck_results().expr_ty(&or_self); // get type of x (we later check if it's Option or Result)
+                let ty = cx.typeck_results().expr_ty(or_self); // get type of x (we later check if it's Option or Result)
                 let title;
 
                 if is_type_diagnostic_item(cx, ty, sym::Option) {
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UseUnwrapOr {
                 span_lint_and_help(
                     cx,
                     USE_UNWRAP_OR,
-                    or_span.to(unwrap_span),
+                    or_span.to(*unwrap_span),
                     title,
                     None,
                     "use `unwrap_or()` instead"
diff --git a/tests/ui/use_unwrap_or.rs b/tests/ui/use_unwrap_or.rs
index 685fab80206..dd55b33739d 100644
--- a/tests/ui/use_unwrap_or.rs
+++ b/tests/ui/use_unwrap_or.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::use_unwrap_or)]
+#![allow(clippy::map_identity)]
 
 struct SomeStruct {}
 impl SomeStruct {
@@ -8,6 +9,14 @@ impl SomeStruct {
     fn unwrap(&self) {}
 }
 
+struct SomeOtherStruct {}
+impl SomeOtherStruct {
+    fn or(self) -> Self {
+        self
+    }
+    fn unwrap(&self) {}
+}
+
 fn main() {
     let option: Option<&str> = None;
     let _ = option.or(Some("fallback")).unwrap(); // should trigger lint
@@ -19,6 +28,9 @@ fn main() {
     let instance = SomeStruct {};
     let _ = instance.or(Some(SomeStruct {})).unwrap(); // should not trigger lint
 
+    let instance = SomeOtherStruct {};
+    let _ = instance.or().unwrap(); // should not trigger lint and should not panic
+
     // None in or
     let option: Option<&str> = None;
     let _ = option.or(None).unwrap(); // should not trigger lint
@@ -26,4 +38,8 @@ fn main() {
     // Not Err in or
     let result: Result<&str, &str> = Err("Error");
     let _ = result.or::<&str>(Err("Other Error")).unwrap(); // should not trigger lint
+
+    // other function between
+    let option: Option<&str> = None;
+    let _ = option.or(Some("fallback")).map(|v| v).unwrap(); // should not trigger lint
 }
diff --git a/tests/ui/use_unwrap_or.stderr b/tests/ui/use_unwrap_or.stderr
index 2e1e920795d..796778a293d 100644
--- a/tests/ui/use_unwrap_or.stderr
+++ b/tests/ui/use_unwrap_or.stderr
@@ -1,5 +1,5 @@
 error: .or(Some(…)).unwrap() found
-  --> $DIR/use_unwrap_or.rs:13:20
+  --> $DIR/use_unwrap_or.rs:22:20
    |
 LL |     let _ = option.or(Some("fallback")).unwrap(); // should trigger lint
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let _ = option.or(Some("fallback")).unwrap(); // should trigger lint
    = help: use `unwrap_or()` instead
 
 error: .or(Ok(…)).unwrap() found
-  --> $DIR/use_unwrap_or.rs:16:20
+  --> $DIR/use_unwrap_or.rs:25:20
    |
 LL |     let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^