Fix ICE with 'while let (..) = x.iter()'

This commit is contained in:
Philipp Hansch 2018-07-28 11:51:46 +02:00
parent fde487c1dc
commit 946340acfe
No known key found for this signature in database
GPG Key ID: B6FA06A6E0E2665B
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