Skip to content

Commit 3174c05

Browse files
authored
fix: unnecessary_map_or don't add parens if the parent expr comes f… (#15345)
…rom a macro changelog: [`unnecessary_map_or`]: don't add parens if the parent expr comes from a macro fixes #14714
2 parents f126db4 + 81fc227 commit 3174c05

File tree

4 files changed

+77
-7
lines changed

4 files changed

+77
-7
lines changed

clippy_lints/src/methods/unnecessary_map_or.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,16 @@ pub(super) fn check<'a>(
109109
);
110110

111111
let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) {
112-
match parent_expr.kind {
113-
ExprKind::Binary(..) | ExprKind::Unary(..) | ExprKind::Cast(..) => binop.maybe_paren(),
114-
ExprKind::MethodCall(_, receiver, _, _) if receiver.hir_id == expr.hir_id => binop.maybe_paren(),
115-
_ => binop,
112+
if parent_expr.span.eq_ctxt(expr.span) {
113+
match parent_expr.kind {
114+
ExprKind::Binary(..) | ExprKind::Unary(..) | ExprKind::Cast(..) => binop.maybe_paren(),
115+
ExprKind::MethodCall(_, receiver, _, _) if receiver.hir_id == expr.hir_id => binop.maybe_paren(),
116+
_ => binop,
117+
}
118+
} else {
119+
// if our parent expr is created by a macro, then it should be the one taking care of
120+
// parenthesising us if necessary
121+
binop
116122
}
117123
} else {
118124
binop

tests/ui/unnecessary_map_or.fixed

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,26 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
131131
x && y
132132
}
133133

134+
fn issue14714() {
135+
assert!(Some("test") == Some("test"));
136+
//~^ unnecessary_map_or
137+
138+
// even though we're in a macro context, we still need to parenthesise because of the `then`
139+
assert!((Some("test") == Some("test")).then(|| 1).is_some());
140+
//~^ unnecessary_map_or
141+
142+
// method lints don't fire on macros
143+
macro_rules! m {
144+
($x:expr) => {
145+
// should become !($x == Some(1))
146+
let _ = !$x.map_or(false, |v| v == 1);
147+
// should become $x == Some(1)
148+
let _ = $x.map_or(false, |v| v == 1);
149+
};
150+
}
151+
m!(Some(5));
152+
}
153+
134154
fn issue15180() {
135155
let s = std::sync::Mutex::new(Some("foo"));
136156
_ = s.lock().unwrap().is_some_and(|s| s == "foo");

tests/ui/unnecessary_map_or.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,26 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
135135
x && y
136136
}
137137

138+
fn issue14714() {
139+
assert!(Some("test").map_or(false, |x| x == "test"));
140+
//~^ unnecessary_map_or
141+
142+
// even though we're in a macro context, we still need to parenthesise because of the `then`
143+
assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some());
144+
//~^ unnecessary_map_or
145+
146+
// method lints don't fire on macros
147+
macro_rules! m {
148+
($x:expr) => {
149+
// should become !($x == Some(1))
150+
let _ = !$x.map_or(false, |v| v == 1);
151+
// should become $x == Some(1)
152+
let _ = $x.map_or(false, |v| v == 1);
153+
};
154+
}
155+
m!(Some(5));
156+
}
157+
138158
fn issue15180() {
139159
let s = std::sync::Mutex::new(Some("foo"));
140160
_ = s.lock().unwrap().map_or(false, |s| s == "foo");

tests/ui/unnecessary_map_or.stderr

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,31 @@ LL + let y = b.is_none_or(|b| b == *s);
327327
|
328328

329329
error: this `map_or` can be simplified
330-
--> tests/ui/unnecessary_map_or.rs:140:9
330+
--> tests/ui/unnecessary_map_or.rs:139:13
331+
|
332+
LL | assert!(Some("test").map_or(false, |x| x == "test"));
333+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
334+
|
335+
help: use a standard comparison instead
336+
|
337+
LL - assert!(Some("test").map_or(false, |x| x == "test"));
338+
LL + assert!(Some("test") == Some("test"));
339+
|
340+
341+
error: this `map_or` can be simplified
342+
--> tests/ui/unnecessary_map_or.rs:143:13
343+
|
344+
LL | assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some());
345+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
346+
|
347+
help: use a standard comparison instead
348+
|
349+
LL - assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some());
350+
LL + assert!((Some("test") == Some("test")).then(|| 1).is_some());
351+
|
352+
353+
error: this `map_or` can be simplified
354+
--> tests/ui/unnecessary_map_or.rs:160:9
331355
|
332356
LL | _ = s.lock().unwrap().map_or(false, |s| s == "foo");
333357
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -339,7 +363,7 @@ LL + _ = s.lock().unwrap().is_some_and(|s| s == "foo");
339363
|
340364

341365
error: this `map_or` can be simplified
342-
--> tests/ui/unnecessary_map_or.rs:144:9
366+
--> tests/ui/unnecessary_map_or.rs:164:9
343367
|
344368
LL | _ = s.map_or(false, |s| s == "foo");
345369
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,5 +374,5 @@ LL - _ = s.map_or(false, |s| s == "foo");
350374
LL + _ = s.is_some_and(|s| s == "foo");
351375
|
352376

353-
error: aborting due to 28 previous errors
377+
error: aborting due to 30 previous errors
354378

0 commit comments

Comments
 (0)