Skip to content

Commit 7ee81ae

Browse files
committed
Fix single_match suggestions with expanded macros
1 parent 1e0729d commit 7ee81ae

File tree

4 files changed

+57
-24
lines changed

4 files changed

+57
-24
lines changed

clippy_lints/src/matches.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_exte
1313
use crate::rustc::{declare_tool_lint, lint_array};
1414
use if_chain::if_chain;
1515
use crate::rustc::ty::{self, Ty};
16+
use std::borrow::Cow;
1617
use std::cmp::Ordering;
1718
use std::collections::Bound;
1819
use crate::syntax::ast::LitKind;
1920
use crate::syntax::source_map::Span;
2021
use crate::utils::paths;
21-
use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
22+
use crate::utils::{expr_block, in_macro, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
2223
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty};
2324
use crate::utils::sugg::Sugg;
2425
use crate::consts::{constant, Constant};
@@ -254,7 +255,18 @@ fn report_single_match_single_pattern(cx: &LateContext<'_, '_>, ex: &Expr, arms:
254255
} else {
255256
SINGLE_MATCH
256257
};
257-
let els_str = els.map_or(String::new(), |els| format!(" else {}", expr_block(cx, els, None, "..")));
258+
let els_str = els.map_or(String::new(), |els| {
259+
if in_macro(els.span) {
260+
" else { .. }".to_string()
261+
} else {
262+
format!(" else {}", expr_block(cx, els, None, ".."))
263+
}
264+
});
265+
let expr_block = if in_macro(arms[0].body.span) {
266+
Cow::Owned("{ .. }".to_string())
267+
} else {
268+
expr_block(cx, &arms[0].body, None, "..")
269+
};
258270
span_lint_and_sugg(
259271
cx,
260272
lint,
@@ -266,7 +278,7 @@ fn report_single_match_single_pattern(cx: &LateContext<'_, '_>, ex: &Expr, arms:
266278
"if let {} = {} {}{}",
267279
snippet(cx, arms[0].pats[0].span, ".."),
268280
snippet(cx, ex.span, ".."),
269-
expr_block(cx, &arms[0].body, None, ".."),
281+
expr_block,
270282
els_str
271283
),
272284
);

tests/ui/matches.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ error: you seem to be trying to use match for destructuring a single pattern. Co
3333
51 | | &(v, 1) => println!("{}", v),
3434
52 | | _ => println!("none"),
3535
53 | | }
36-
| |_____^ help: try this: `if let &(v, 1) = tup { $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ; } else { $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ; }`
36+
| |_____^ help: try this: `if let &(v, 1) = tup { .. } else { .. }`
3737

3838
error: you don't need to add `&` to all patterns
3939
--> $DIR/matches.rs:50:5

tests/ui/single_match.rs

+9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ fn single_match(){
2323
_ => ()
2424
};
2525

26+
let x = Some(1u8);
27+
match x {
28+
// Note the missing block braces.
29+
// We suggest `if let Some(y) = x { .. }` because the macro
30+
// is expanded before we can do anything.
31+
Some(y) => println!("{:?}", y),
32+
_ => ()
33+
}
34+
2635
let z = (1u8,1u8);
2736
match z {
2837
(2...3, 7...9) => dummy(),

tests/ui/single_match.stderr

+32-20
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,50 @@ error: you seem to be trying to use match for destructuring a single pattern. Co
1212
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
1313
--> $DIR/single_match.rs:27:5
1414
|
15-
27 | / match z {
16-
28 | | (2...3, 7...9) => dummy(),
17-
29 | | _ => {}
18-
30 | | };
15+
27 | / match x {
16+
28 | | // Note the missing block braces.
17+
29 | | // We suggest `if let Some(y) = x { .. }` because the macro
18+
30 | | // is expanded before we can do anything.
19+
31 | | Some(y) => println!("{:?}", y),
20+
32 | | _ => ()
21+
33 | | }
22+
| |_____^ help: try this: `if let Some(y) = x { .. }`
23+
24+
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
25+
--> $DIR/single_match.rs:36:5
26+
|
27+
36 | / match z {
28+
37 | | (2...3, 7...9) => dummy(),
29+
38 | | _ => {}
30+
39 | | };
1931
| |_____^ help: try this: `if let (2...3, 7...9) = z { dummy() }`
2032

2133
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
22-
--> $DIR/single_match.rs:53:5
34+
--> $DIR/single_match.rs:62:5
2335
|
24-
53 | / match x {
25-
54 | | Some(y) => dummy(),
26-
55 | | None => ()
27-
56 | | };
36+
62 | / match x {
37+
63 | | Some(y) => dummy(),
38+
64 | | None => ()
39+
65 | | };
2840
| |_____^ help: try this: `if let Some(y) = x { dummy() }`
2941

3042
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
31-
--> $DIR/single_match.rs:58:5
43+
--> $DIR/single_match.rs:67:5
3244
|
33-
58 | / match y {
34-
59 | | Ok(y) => dummy(),
35-
60 | | Err(..) => ()
36-
61 | | };
45+
67 | / match y {
46+
68 | | Ok(y) => dummy(),
47+
69 | | Err(..) => ()
48+
70 | | };
3749
| |_____^ help: try this: `if let Ok(y) = y { dummy() }`
3850

3951
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
40-
--> $DIR/single_match.rs:65:5
52+
--> $DIR/single_match.rs:74:5
4153
|
42-
65 | / match c {
43-
66 | | Cow::Borrowed(..) => dummy(),
44-
67 | | Cow::Owned(..) => (),
45-
68 | | };
54+
74 | / match c {
55+
75 | | Cow::Borrowed(..) => dummy(),
56+
76 | | Cow::Owned(..) => (),
57+
77 | | };
4658
| |_____^ help: try this: `if let Cow::Borrowed(..) = c { dummy() }`
4759

48-
error: aborting due to 5 previous errors
60+
error: aborting due to 6 previous errors
4961

0 commit comments

Comments
 (0)