Auto merge of #3672 - mikerite:fix-3670, r=oli-obk

Fix bad `while_let_on_iterator` suggestion.

Don't suggest a `for` loop if the iterator is used inside the `while` loop.

Closes #3670
This commit is contained in:
bors 2019-01-19 11:12:03 +00:00
commit 751d82e825
2 changed files with 24 additions and 0 deletions

View File

@ -565,6 +565,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
&& lhs_constructor.ident.name == "Some"
&& (pat_args.is_empty()
|| !is_refutable(cx, &pat_args[0])
&& !is_used_inside(cx, iter_expr, &arms[0].body)
&& !is_iterator_used_after_while_let(cx, iter_expr)
&& !is_nested(cx, expr, &method_args[0]))
{
@ -1888,6 +1889,19 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
}
}
fn is_used_inside<'a, 'tcx: 'a>(cx: &'a LateContext<'a, 'tcx>, expr: &'tcx Expr, container: &'tcx Expr) -> bool {
let def_id = match var_def_id(cx, expr) {
Some(id) => id,
None => return false,
};
if let Some(used_mutably) = mutated_variables(container, cx) {
if used_mutably.contains(&def_id) {
return true;
}
}
false
}
fn is_iterator_used_after_while_let<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, iter_expr: &'tcx Expr) -> bool {
let def_id = match var_def_id(cx, iter_expr) {
Some(id) => id,

View File

@ -216,4 +216,14 @@ fn refutable() {
while let Some(..) = values.iter().next() {
values.remove(&1);
}
// Issue 3670
{
let array = [Some(0), None, Some(1)];
let mut iter = array.iter();
while let Some(elem) = iter.next() {
let _ = elem.or_else(|| *iter.next()?);
}
}
}