Merge pull request #2968 from phansch/first_an_ICE_and_then_some_ice_cream

Fix ICE with 'while let Some(..) = x.iter()'
This commit is contained in:
Philipp Hansch 2018-08-01 06:18:34 +01:00 committed by GitHub
commit d7ffaab0fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 5 deletions

View file

@ -488,12 +488,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
let iter_expr = &method_args[0];
let lhs_constructor = last_path_segment(qpath);
if method_path.ident.name == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR)
&& lhs_constructor.ident.name == "Some" && !is_refutable(cx, &pat_args[0])
&& !is_iterator_used_after_while_let(cx, iter_expr)
&& !is_nested(cx, expr, &method_args[0])
&& lhs_constructor.ident.name == "Some" && (
pat_args.is_empty()
|| !is_refutable(cx, &pat_args[0])
&& !is_iterator_used_after_while_let(cx, iter_expr)
&& !is_nested(cx, expr, &method_args[0]))
{
let iterator = snippet(cx, method_args[0].span, "_");
let loop_var = snippet(cx, pat_args[0].span, "_");
let loop_var = if pat_args.is_empty() {
"_".to_string()
} else {
snippet(cx, pat_args[0].span, "_").into_owned()
};
span_lint_and_sugg(
cx,
WHILE_LET_ON_ITERATOR,

View file

@ -201,4 +201,13 @@ fn refutable() {
while let Some(&value) = values.iter().next() {
values.remove(&value);
}
// This should not cause an ICE and suggest:
//
// for _ in values.iter() {}
//
// See #2965
while let Some(..) = values.iter().next() {
values.remove(&1);
}
}

View file

@ -105,5 +105,11 @@ error: this loop could be written as a `for` loop
183 | while let Some(v) = y.next() { // use a for loop here
| ^^^^^^^^ help: try: `for v in y { .. }`
error: aborting due to 11 previous errors
error: this loop could be written as a `for` loop
--> $DIR/while_loop.rs:210:26
|
210 | while let Some(..) = values.iter().next() {
| ^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in values.iter() { .. }`
error: aborting due to 12 previous errors