about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Wagner-Hall <dawagner@gmail.com>2025-08-14 00:53:34 +0100
committerDaniel Wagner-Hall <dawagner@gmail.com>2025-08-14 00:53:34 +0100
commit0170d6cecd1e8592774ccd94dd2a5bf30ff2495a (patch)
treea95b4cad9062af953f368e107ce11a63641c823a
parentb3faf62b288709f76c45459bff9110bbea37694b (diff)
or_then_unwrap suggestion preserves macro calls
Before this change, the suggestion for
`Option.or(Some(vec![])).unwrap()` expanded the `vec!` macro which broke
the code, both in terms of readability, and because the expansion
references `$crate` which cannot be inlined.
-rw-r--r--clippy_lints/src/methods/or_then_unwrap.rs2
-rw-r--r--tests/ui/or_then_unwrap.fixed6
-rw-r--r--tests/ui/or_then_unwrap.rs6
-rw-r--r--tests/ui/or_then_unwrap.stderr10
4 files changed, 21 insertions, 3 deletions
diff --git a/clippy_lints/src/methods/or_then_unwrap.rs b/clippy_lints/src/methods/or_then_unwrap.rs
index 3e64e15dc86..1a760ea733d 100644
--- a/clippy_lints/src/methods/or_then_unwrap.rs
+++ b/clippy_lints/src/methods/or_then_unwrap.rs
@@ -62,7 +62,7 @@ fn get_content_if_ctor_matches(cx: &LateContext<'_>, expr: &Expr<'_>, item: Lang
     if let ExprKind::Call(some_expr, [arg]) = expr.kind
         && is_res_lang_ctor(cx, path_res(cx, some_expr), item)
     {
-        Some(arg.span)
+        Some(arg.span.source_callsite())
     } else {
         None
     }
diff --git a/tests/ui/or_then_unwrap.fixed b/tests/ui/or_then_unwrap.fixed
index ba9beef57af..9660b82fe7d 100644
--- a/tests/ui/or_then_unwrap.fixed
+++ b/tests/ui/or_then_unwrap.fixed
@@ -28,6 +28,12 @@ fn main() {
     //
     //~^^ or_then_unwrap
 
+    // Call with macro should preserve the macro call rather than expand it
+    let option: Option<Vec<&str>> = None;
+    let _ = option.unwrap_or(vec!["fallback"]); // should trigger lint
+    //
+    //~^^ or_then_unwrap
+
     // as part of a method chain
     let option: Option<&str> = None;
     let _ = option.map(|v| v).unwrap_or("fallback").to_string().chars(); // should trigger lint
diff --git a/tests/ui/or_then_unwrap.rs b/tests/ui/or_then_unwrap.rs
index fac90249a24..c3873352116 100644
--- a/tests/ui/or_then_unwrap.rs
+++ b/tests/ui/or_then_unwrap.rs
@@ -28,6 +28,12 @@ fn main() {
     //
     //~^^ or_then_unwrap
 
+    // Call with macro should preserve the macro call rather than expand it
+    let option: Option<Vec<&str>> = None;
+    let _ = option.or(Some(vec!["fallback"])).unwrap(); // should trigger lint
+    //
+    //~^^ or_then_unwrap
+
     // as part of a method chain
     let option: Option<&str> = None;
     let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint
diff --git a/tests/ui/or_then_unwrap.stderr b/tests/ui/or_then_unwrap.stderr
index 1160498c605..3e66b15edbd 100644
--- a/tests/ui/or_then_unwrap.stderr
+++ b/tests/ui/or_then_unwrap.stderr
@@ -14,10 +14,16 @@ LL |     let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger l
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
 
 error: found `.or(Some(…)).unwrap()`
-  --> tests/ui/or_then_unwrap.rs:33:31
+  --> tests/ui/or_then_unwrap.rs:33:20
+   |
+LL |     let _ = option.or(Some(vec!["fallback"])).unwrap(); // should trigger lint
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or(vec!["fallback"])`
+
+error: found `.or(Some(…)).unwrap()`
+  --> tests/ui/or_then_unwrap.rs:39:31
    |
 LL |     let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors