Skip to content

Commit efb10c7

Browse files
authored
Rollup merge of rust-lang#131492 - flip1995:clippy-master-backport, r=matthiaskrgr
Clippy: Backport `needless_return` fix r? ``@Manishearth`` This cherry-picks rust-lang/rust-clippy#13464, so that it gets into master and with that into `beta` tomorrow, so that the bug in this lint doesn't hit `beta`. Changes look quite big, but most of them are whitespace changes because of the introduction of an `_inner` function. In reality it only adds 2 checks.
2 parents 33053d3 + a21a9fe commit efb10c7

File tree

7 files changed

+154
-111
lines changed

7 files changed

+154
-111
lines changed

src/tools/clippy/clippy_lints/src/returns.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ fn check_final_expr<'tcx>(
407407
}
408408
}
409409

410-
if ret_span.from_expansion() {
410+
if ret_span.from_expansion() || is_from_proc_macro(cx, expr) {
411411
return;
412412
}
413413

src/tools/clippy/clippy_utils/src/check_proc_macro.rs

+81-54
Original file line numberDiff line numberDiff line change
@@ -141,62 +141,89 @@ fn path_search_pat(path: &Path<'_>) -> (Pat, Pat) {
141141

142142
/// Get the search patterns to use for the given expression
143143
fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
144-
match e.kind {
145-
ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")),
146-
// Parenthesis are trimmed from the text before the search patterns are matched.
147-
// See: `span_matches_pat`
148-
ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")),
149-
ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1),
150-
ExprKind::Unary(UnOp::Not, e) => (Pat::Str("!"), expr_search_pat(tcx, e).1),
151-
ExprKind::Unary(UnOp::Neg, e) => (Pat::Str("-"), expr_search_pat(tcx, e).1),
152-
ExprKind::Lit(lit) => lit_search_pat(&lit.node),
153-
ExprKind::Array(_) | ExprKind::Repeat(..) => (Pat::Str("["), Pat::Str("]")),
154-
ExprKind::Call(e, []) | ExprKind::MethodCall(_, e, [], _) => (expr_search_pat(tcx, e).0, Pat::Str("(")),
155-
ExprKind::Call(first, [.., last])
156-
| ExprKind::MethodCall(_, first, [.., last], _)
157-
| ExprKind::Binary(_, first, last)
158-
| ExprKind::Tup([first, .., last])
159-
| ExprKind::Assign(first, last, _)
160-
| ExprKind::AssignOp(_, first, last) => (expr_search_pat(tcx, first).0, expr_search_pat(tcx, last).1),
161-
ExprKind::Tup([e]) | ExprKind::DropTemps(e) => expr_search_pat(tcx, e),
162-
ExprKind::Cast(e, _) | ExprKind::Type(e, _) => (expr_search_pat(tcx, e).0, Pat::Str("")),
163-
ExprKind::Let(let_expr) => (Pat::Str("let"), expr_search_pat(tcx, let_expr.init).1),
164-
ExprKind::If(..) => (Pat::Str("if"), Pat::Str("}")),
165-
ExprKind::Loop(_, Some(_), _, _) | ExprKind::Block(_, Some(_)) => (Pat::Str("'"), Pat::Str("}")),
166-
ExprKind::Loop(_, None, LoopSource::Loop, _) => (Pat::Str("loop"), Pat::Str("}")),
167-
ExprKind::Loop(_, None, LoopSource::While, _) => (Pat::Str("while"), Pat::Str("}")),
168-
ExprKind::Loop(_, None, LoopSource::ForLoop, _) | ExprKind::Match(_, _, MatchSource::ForLoopDesugar) => {
169-
(Pat::Str("for"), Pat::Str("}"))
170-
},
171-
ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str("match"), Pat::Str("}")),
172-
ExprKind::Match(e, _, MatchSource::TryDesugar(_)) => (expr_search_pat(tcx, e).0, Pat::Str("?")),
173-
ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {
174-
(expr_search_pat(tcx, e).0, Pat::Str("await"))
175-
},
176-
ExprKind::Closure(&Closure { body, .. }) => (Pat::Str(""), expr_search_pat(tcx, tcx.hir().body(body).value).1),
177-
ExprKind::Block(
178-
Block {
179-
rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
180-
..
144+
fn expr_search_pat_inner(tcx: TyCtxt<'_>, e: &Expr<'_>, outer_span: Span) -> (Pat, Pat) {
145+
// The expression can have subexpressions in different contexts, in which case
146+
// building up a search pattern from the macro expansion would lead to false positives;
147+
// e.g. `return format!(..)` would be considered to be from a proc macro
148+
// if we build up a pattern for the macro expansion and compare it to the invocation `format!()`.
149+
// So instead we return an empty pattern such that `span_matches_pat` always returns true.
150+
if !e.span.eq_ctxt(outer_span) {
151+
return (Pat::Str(""), Pat::Str(""));
152+
}
153+
154+
match e.kind {
155+
ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")),
156+
// Parenthesis are trimmed from the text before the search patterns are matched.
157+
// See: `span_matches_pat`
158+
ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")),
159+
ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat_inner(tcx, e, outer_span).1),
160+
ExprKind::Unary(UnOp::Not, e) => (Pat::Str("!"), expr_search_pat_inner(tcx, e, outer_span).1),
161+
ExprKind::Unary(UnOp::Neg, e) => (Pat::Str("-"), expr_search_pat_inner(tcx, e, outer_span).1),
162+
ExprKind::Lit(lit) => lit_search_pat(&lit.node),
163+
ExprKind::Array(_) | ExprKind::Repeat(..) => (Pat::Str("["), Pat::Str("]")),
164+
ExprKind::Call(e, []) | ExprKind::MethodCall(_, e, [], _) => {
165+
(expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str("("))
181166
},
182-
None,
183-
) => (Pat::Str("unsafe"), Pat::Str("}")),
184-
ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
185-
ExprKind::Field(e, name) => (expr_search_pat(tcx, e).0, Pat::Sym(name.name)),
186-
ExprKind::Index(e, _, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
187-
ExprKind::Path(ref path) => qpath_search_pat(path),
188-
ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1),
189-
ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),
190-
ExprKind::Break(Destination { label: Some(name), .. }, None) => (Pat::Str("break"), Pat::Sym(name.ident.name)),
191-
ExprKind::Break(_, Some(e)) => (Pat::Str("break"), expr_search_pat(tcx, e).1),
192-
ExprKind::Continue(Destination { label: None, .. }) => (Pat::Str("continue"), Pat::Str("continue")),
193-
ExprKind::Continue(Destination { label: Some(name), .. }) => (Pat::Str("continue"), Pat::Sym(name.ident.name)),
194-
ExprKind::Ret(None) => (Pat::Str("return"), Pat::Str("return")),
195-
ExprKind::Ret(Some(e)) => (Pat::Str("return"), expr_search_pat(tcx, e).1),
196-
ExprKind::Struct(path, _, _) => (qpath_search_pat(path).0, Pat::Str("}")),
197-
ExprKind::Yield(e, YieldSource::Yield) => (Pat::Str("yield"), expr_search_pat(tcx, e).1),
198-
_ => (Pat::Str(""), Pat::Str("")),
167+
ExprKind::Call(first, [.., last])
168+
| ExprKind::MethodCall(_, first, [.., last], _)
169+
| ExprKind::Binary(_, first, last)
170+
| ExprKind::Tup([first, .., last])
171+
| ExprKind::Assign(first, last, _)
172+
| ExprKind::AssignOp(_, first, last) => (
173+
expr_search_pat_inner(tcx, first, outer_span).0,
174+
expr_search_pat_inner(tcx, last, outer_span).1,
175+
),
176+
ExprKind::Tup([e]) | ExprKind::DropTemps(e) => expr_search_pat_inner(tcx, e, outer_span),
177+
ExprKind::Cast(e, _) | ExprKind::Type(e, _) => (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str("")),
178+
ExprKind::Let(let_expr) => (Pat::Str("let"), expr_search_pat_inner(tcx, let_expr.init, outer_span).1),
179+
ExprKind::If(..) => (Pat::Str("if"), Pat::Str("}")),
180+
ExprKind::Loop(_, Some(_), _, _) | ExprKind::Block(_, Some(_)) => (Pat::Str("'"), Pat::Str("}")),
181+
ExprKind::Loop(_, None, LoopSource::Loop, _) => (Pat::Str("loop"), Pat::Str("}")),
182+
ExprKind::Loop(_, None, LoopSource::While, _) => (Pat::Str("while"), Pat::Str("}")),
183+
ExprKind::Loop(_, None, LoopSource::ForLoop, _) | ExprKind::Match(_, _, MatchSource::ForLoopDesugar) => {
184+
(Pat::Str("for"), Pat::Str("}"))
185+
},
186+
ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str("match"), Pat::Str("}")),
187+
ExprKind::Match(e, _, MatchSource::TryDesugar(_)) => {
188+
(expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str("?"))
189+
},
190+
ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {
191+
(expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str("await"))
192+
},
193+
ExprKind::Closure(&Closure { body, .. }) => (
194+
Pat::Str(""),
195+
expr_search_pat_inner(tcx, tcx.hir().body(body).value, outer_span).1,
196+
),
197+
ExprKind::Block(
198+
Block {
199+
rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
200+
..
201+
},
202+
None,
203+
) => (Pat::Str("unsafe"), Pat::Str("}")),
204+
ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
205+
ExprKind::Field(e, name) => (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Sym(name.name)),
206+
ExprKind::Index(e, _, _) => (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str("]")),
207+
ExprKind::Path(ref path) => qpath_search_pat(path),
208+
ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat_inner(tcx, e, outer_span).1),
209+
ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),
210+
ExprKind::Break(Destination { label: Some(name), .. }, None) => {
211+
(Pat::Str("break"), Pat::Sym(name.ident.name))
212+
},
213+
ExprKind::Break(_, Some(e)) => (Pat::Str("break"), expr_search_pat_inner(tcx, e, outer_span).1),
214+
ExprKind::Continue(Destination { label: None, .. }) => (Pat::Str("continue"), Pat::Str("continue")),
215+
ExprKind::Continue(Destination { label: Some(name), .. }) => {
216+
(Pat::Str("continue"), Pat::Sym(name.ident.name))
217+
},
218+
ExprKind::Ret(None) => (Pat::Str("return"), Pat::Str("return")),
219+
ExprKind::Ret(Some(e)) => (Pat::Str("return"), expr_search_pat_inner(tcx, e, outer_span).1),
220+
ExprKind::Struct(path, _, _) => (qpath_search_pat(path).0, Pat::Str("}")),
221+
ExprKind::Yield(e, YieldSource::Yield) => (Pat::Str("yield"), expr_search_pat_inner(tcx, e, outer_span).1),
222+
_ => (Pat::Str(""), Pat::Str("")),
223+
}
199224
}
225+
226+
expr_search_pat_inner(tcx, e, e.span)
200227
}
201228

202229
fn fn_header_search_pat(header: FnHeader) -> Pat {

src/tools/clippy/tests/ui/dbg_macro/dbg_macro.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![warn(clippy::dbg_macro)]
2-
#![allow(clippy::unnecessary_operation, clippy::no_effect)]
2+
#![allow(clippy::unnecessary_operation, clippy::no_effect, clippy::unit_arg)]
33

44
fn foo(n: u32) -> u32 {
55
if let Some(n) = n.checked_sub(4) { n } else { n }

src/tools/clippy/tests/ui/dbg_macro/dbg_macro.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![warn(clippy::dbg_macro)]
2-
#![allow(clippy::unnecessary_operation, clippy::no_effect)]
2+
#![allow(clippy::unnecessary_operation, clippy::no_effect, clippy::unit_arg)]
33

44
fn foo(n: u32) -> u32 {
55
if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }

src/tools/clippy/tests/ui/needless_return.fixed

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@aux-build:proc_macros.rs
12
#![feature(yeet_expr)]
23
#![allow(unused)]
34
#![allow(
@@ -9,6 +10,9 @@
910
)]
1011
#![warn(clippy::needless_return)]
1112

13+
extern crate proc_macros;
14+
use proc_macros::with_span;
15+
1216
use std::cell::RefCell;
1317

1418
macro_rules! the_answer {
@@ -359,6 +363,10 @@ fn issue12907() -> String {
359363
"".split("").next().unwrap().to_string()
360364
}
361365

366+
fn issue13458() {
367+
with_span!(span return);
368+
}
369+
362370
fn main() {}
363371

364372
fn a(x: Option<u8>) -> Option<u8> {

src/tools/clippy/tests/ui/needless_return.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@aux-build:proc_macros.rs
12
#![feature(yeet_expr)]
23
#![allow(unused)]
34
#![allow(
@@ -9,6 +10,9 @@
910
)]
1011
#![warn(clippy::needless_return)]
1112

13+
extern crate proc_macros;
14+
use proc_macros::with_span;
15+
1216
use std::cell::RefCell;
1317

1418
macro_rules! the_answer {
@@ -369,6 +373,10 @@ fn issue12907() -> String {
369373
return "".split("").next().unwrap().to_string();
370374
}
371375

376+
fn issue13458() {
377+
with_span!(span return);
378+
}
379+
372380
fn main() {}
373381

374382
fn a(x: Option<u8>) -> Option<u8> {

0 commit comments

Comments
 (0)