mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-15 01:17:16 +00:00
Avoid to suggest using label
This commit is contained in:
parent
5bb0f16552
commit
90cbbb2da3
3 changed files with 25 additions and 51 deletions
|
@ -31,26 +31,20 @@ pub(super) fn lint(cx: &LateContext<'_>, expr: &'tcx Expr<'_>, args: &[&[Expr<'_
|
|||
let body = cx.tcx.hir().body(body_id);
|
||||
if let ExprKind::Block(..) = body.value.kind;
|
||||
then {
|
||||
let mut ret_span_collector = RetSpanCollector::new();
|
||||
ret_span_collector.visit_expr(&body.value);
|
||||
let mut ret_collector = RetCollector::new();
|
||||
ret_collector.visit_expr(&body.value);
|
||||
|
||||
// Skip the lint if `return` is used in `Loop` to avoid a suggest using `'label`.
|
||||
if ret_collector.ret_in_loop {
|
||||
return;
|
||||
}
|
||||
|
||||
let label = "'outer";
|
||||
let loop_label = if ret_span_collector.need_label {
|
||||
format!("{}: ", label)
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let sugg =
|
||||
format!("{}for {} in {} {{ .. }}", loop_label, snippet(cx, body.params[0].pat.span, ""), snippet(cx, for_each_receiver.span, ""));
|
||||
format!("for {} in {} {{ .. }}", snippet(cx, body.params[0].pat.span, ""), snippet(cx, for_each_receiver.span, ""));
|
||||
|
||||
let mut notes = vec![];
|
||||
for (span, need_label) in ret_span_collector.spans {
|
||||
let cont_label = if need_label {
|
||||
format!(" {}", label)
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let note = format!("change `return` to `continue{}` in the loop body", cont_label);
|
||||
for span in ret_collector.spans {
|
||||
let note = format!("change `return` to `continue` in the loop body");
|
||||
notes.push((span, note));
|
||||
}
|
||||
|
||||
|
@ -100,34 +94,37 @@ fn is_target_ty(cx: &LateContext<'_>, expr_ty: Ty<'_>) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
/// Collect spans of `return` in the closure body.
|
||||
struct RetSpanCollector {
|
||||
spans: Vec<(Span, bool)>,
|
||||
/// This type plays two roles.
|
||||
/// 1. Collect spans of `return` in the closure body.
|
||||
/// 2. Detect use of `return` in `Loop` in the closure body.
|
||||
struct RetCollector {
|
||||
spans: Vec<Span>,
|
||||
ret_in_loop: bool,
|
||||
|
||||
loop_depth: u16,
|
||||
need_label: bool,
|
||||
}
|
||||
|
||||
impl RetSpanCollector {
|
||||
impl RetCollector {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
spans: Vec::new(),
|
||||
ret_in_loop: false,
|
||||
loop_depth: 0,
|
||||
need_label: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RetSpanCollector {
|
||||
impl<'tcx> Visitor<'tcx> for RetCollector {
|
||||
type Map = Map<'tcx>;
|
||||
|
||||
fn visit_expr(&mut self, expr: &Expr<'_>) {
|
||||
match expr.kind {
|
||||
ExprKind::Ret(..) => {
|
||||
if self.loop_depth > 0 && !self.need_label {
|
||||
self.need_label = true
|
||||
if self.loop_depth > 0 && !self.ret_in_loop {
|
||||
self.ret_in_loop = true
|
||||
}
|
||||
|
||||
self.spans.push((expr.span, self.loop_depth > 0))
|
||||
self.spans.push(expr.span)
|
||||
},
|
||||
|
||||
ExprKind::Loop(..) => {
|
||||
|
|
|
@ -82,7 +82,7 @@ fn main() {
|
|||
}
|
||||
});
|
||||
|
||||
// Should trigger this lint with notes that say "change `return` to `continue 'outer`".
|
||||
// Should NOT trigger this lint in case `return` is used in `Loop` of the closure.
|
||||
vec.iter().for_each(|v| {
|
||||
for i in 0..*v {
|
||||
if i == 10 {
|
||||
|
|
|
@ -122,28 +122,5 @@ note: change `return` to `continue` in the loop body
|
|||
LL | return;
|
||||
| ^^^^^^
|
||||
|
||||
error: excessive use of `for_each`
|
||||
--> $DIR/excessive_for_each.rs:86:5
|
||||
|
|
||||
LL | / vec.iter().for_each(|v| {
|
||||
LL | | for i in 0..*v {
|
||||
LL | | if i == 10 {
|
||||
LL | | return;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | });
|
||||
| |______^ help: try: `'outer: for v in vec.iter() { .. }`
|
||||
|
|
||||
note: change `return` to `continue 'outer` in the loop body
|
||||
--> $DIR/excessive_for_each.rs:89:17
|
||||
|
|
||||
LL | return;
|
||||
| ^^^^^^
|
||||
note: change `return` to `continue` in the loop body
|
||||
--> $DIR/excessive_for_each.rs:95:13
|
||||
|
|
||||
LL | return;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue