diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index d6430cf291b..acc7b11e346 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -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,
diff --git a/tests/ui/while_loop.rs b/tests/ui/while_loop.rs
index 283a2d43c04..8c3bf1cc674 100644
--- a/tests/ui/while_loop.rs
+++ b/tests/ui/while_loop.rs
@@ -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()?);
+        }
+    }
 }