about summary refs log tree commit diff
path: root/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs')
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs
new file mode 100644
index 00000000000..00e48b65fed
--- /dev/null
+++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs
@@ -0,0 +1,43 @@
+#![crate_type = "lib"]
+
+// An example from #63908 of the linked-list cursor-like pattern of #46859/#48001.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #63908
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+struct Node<T> {
+    value: T,
+    next: Option<Box<Self>>,
+}
+
+type List<T> = Option<Box<Node<T>>>;
+
+fn remove_last_node_recursive<T>(node_ref: &mut List<T>) {
+    let next_ref = &mut node_ref.as_mut().unwrap().next;
+
+    if next_ref.is_some() {
+        remove_last_node_recursive(next_ref);
+    } else {
+        *node_ref = None;
+    }
+}
+
+// NLLs fail here
+fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) {
+    loop {
+        let next_ref = &mut node_ref.as_mut().unwrap().next;
+
+        if next_ref.is_some() {
+            node_ref = next_ref;
+        } else {
+            break;
+        }
+    }
+
+    *node_ref = None;
+}