Skip to content

Commit 105a14f

Browse files
committed
Merge pull request #721 from mcarton/while_let_loop
Fix wrong suggestion in `WHILE_LET_LOOP`
2 parents 5fe58d5 + 5fadfb3 commit 105a14f

File tree

2 files changed

+22
-25
lines changed

2 files changed

+22
-25
lines changed

src/loops.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_front::intravisit::{Visitor, walk_expr, walk_block, walk_decl};
1111
use std::borrow::Cow;
1212
use std::collections::HashMap;
1313

14-
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro, expr_block,
14+
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro,
1515
span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then, walk_ptrs_ty};
1616
use utils::{BTREEMAP_PATH, HASHMAP_PATH, LL_PATH, OPTION_PATH, RESULT_PATH, VEC_PATH};
1717

@@ -241,20 +241,6 @@ impl LateLintPass for LoopsPass {
241241
// or extract the first expression (if any) from the block
242242
if let Some(inner) = inner_stmt_expr.or_else(|| extract_first_expr(block)) {
243243
if let ExprMatch(ref matchexpr, ref arms, ref source) = inner.node {
244-
// collect the remaining statements below the match
245-
let mut other_stuff = block.stmts
246-
.iter()
247-
.skip(1)
248-
.map(|stmt| snippet(cx, stmt.span, ".."))
249-
.collect::<Vec<Cow<_>>>();
250-
if inner_stmt_expr.is_some() {
251-
// if we have a statement which has a match,
252-
if let Some(ref expr) = block.expr {
253-
// then collect the expression (without semicolon) below it
254-
other_stuff.push(snippet(cx, expr.span, ".."));
255-
}
256-
}
257-
258244
// ensure "if let" compatible match structure
259245
match *source {
260246
MatchSource::Normal | MatchSource::IfLetDesugar{..} => {
@@ -264,22 +250,20 @@ impl LateLintPass for LoopsPass {
264250
if in_external_macro(cx, expr.span) {
265251
return;
266252
}
267-
let loop_body = if inner_stmt_expr.is_some() {
268-
// FIXME: should probably be an ellipsis
269-
// tabbing and newline is probably a bad idea, especially for large blocks
270-
Cow::Owned(format!("{{\n {}\n}}", other_stuff.join("\n ")))
271-
} else {
272-
expr_block(cx, &arms[0].body, Some(other_stuff.join("\n ")), "..")
273-
};
253+
254+
// NOTE: we used to make build a body here instead of using
255+
// ellipsis, this was removed because:
256+
// 1) it was ugly with big bodies;
257+
// 2) it was not indented properly;
258+
// 3) it wasn’t very smart (see #675).
274259
span_lint_and_then(cx,
275260
WHILE_LET_LOOP,
276261
expr.span,
277262
"this loop could be written as a `while let` loop",
278263
|db| {
279-
let sug = format!("while let {} = {} {}",
264+
let sug = format!("while let {} = {} {{ .. }}",
280265
snippet(cx, arms[0].pats[0].span, ".."),
281-
snippet(cx, matchexpr.span, ".."),
282-
loop_body);
266+
snippet(cx, matchexpr.span, ".."));
283267
db.span_suggestion(expr.span, "try", sug);
284268
});
285269
}

tests/compile-fail/while_loop.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ fn main() {
6666
println!("{}", x);
6767
}
6868

69+
// #675, this used to have a wrong suggestion
70+
loop {
71+
//~^ERROR this loop could be written as a `while let` loop
72+
//~|HELP try
73+
//~|SUGGESTION while let Some(word) = "".split_whitespace().next() { .. }
74+
let (e, l) = match "".split_whitespace().next() {
75+
Some(word) => (word.is_empty(), word.len()),
76+
None => break
77+
};
78+
79+
let _ = (e, l);
80+
}
81+
6982
let mut iter = 1..20;
7083
while let Option::Some(x) = iter.next() { //~ERROR this loop could be written as a `for` loop
7184
println!("{}", x);

0 commit comments

Comments
 (0)