about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-08-08 12:52:58 +1000
committerGitHub <noreply@github.com>2025-08-08 12:52:58 +1000
commitab0b90f61260f0eb9067439e5b787a8a17a89f52 (patch)
treee46c491175cafbf7637b75c70dc988970f3d2e94
parent432a4f27fe5f1703af0277cd6b2e855ec47996f4 (diff)
parent202963f2215245180fa985f3640a582554656253 (diff)
downloadrust-ab0b90f61260f0eb9067439e5b787a8a17a89f52.tar.gz
rust-ab0b90f61260f0eb9067439e5b787a8a17a89f52.zip
Rollup merge of #145053 - lqd:known-bugs, r=jackh726
Add a lot of NLL `known-bug` tests

r? ``@jackh726``

As requested in https://github.com/rust-lang/rust/pull/143093#pullrequestreview-3058256280 this extracts most tests from that PR and expands upon them as described.

The handful of linked-list cursor-like tests will also turn into polonius=next known-bugs in rust-lang/rust#143093 where the behavior w/r/t kills changes of course.
-rw-r--r--tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr14
-rw-r--r--tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs56
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr12
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs47
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr22
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs44
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr18
-rw-r--r--tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs43
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr17
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs25
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr16
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs40
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr17
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs30
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr34
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs45
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr96
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs85
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr18
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs30
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr15
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs28
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr16
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs25
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr112
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs74
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr17
-rw-r--r--tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs38
28 files changed, 1034 insertions, 0 deletions
diff --git a/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr
new file mode 100644
index 00000000000..d5c85a2af23
--- /dev/null
+++ b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr
@@ -0,0 +1,14 @@
+error[E0499]: cannot borrow `self.iter` as mutable more than once at a time
+  --> $DIR/filtering-lending-iterator-issue-92985.rs:49:32
+   |
+LL |     fn next(&mut self) -> Option<I::Item<'_>> {
+   |             - let's call the lifetime of this reference `'1`
+LL |         while let Some(item) = self.iter.next() {
+   |                                ^^^^^^^^^ `self.iter` was mutably borrowed here in the previous iteration of the loop
+LL |             if (self.predicate)(&item) {
+LL |                 return Some(item);
+   |                        ---------- returning this value requires that `self.iter` is borrowed for `'1`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs
new file mode 100644
index 00000000000..27da62ef00b
--- /dev/null
+++ b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs
@@ -0,0 +1,56 @@
+#![crate_type = "lib"]
+
+// This test is an example of a filtering lending iterator with GATs from #92985 (that is similar to
+// NLL problem case #3) to ensure it "works" with the polonius alpha analysis as with the datalog
+// implementation.
+//
+// The polonius analysis only changes how the `Filter::next` function is borrowcked, not the bounds
+// on the predicate from using the GAT. So even if the #92985 limitation is removed, the unrelated
+// 'static limitation on the predicate argument is still there, and the pattern is still impractical
+// to use in the real world.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #92985
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+trait LendingIterator {
+    type Item<'a>
+    where
+        Self: 'a;
+    fn next(&mut self) -> Option<Self::Item<'_>>;
+
+    fn filter<P>(self, predicate: P) -> Filter<Self, P>
+    where
+        Self: Sized,
+        P: FnMut(&Self::Item<'_>) -> bool,
+    {
+        Filter { iter: self, predicate }
+    }
+}
+
+pub struct Filter<I, P> {
+    iter: I,
+    predicate: P,
+}
+impl<I: LendingIterator, P> LendingIterator for Filter<I, P>
+where
+    P: FnMut(&I::Item<'_>) -> bool,
+{
+    type Item<'a>
+        = I::Item<'a>
+    where
+        Self: 'a;
+
+    fn next(&mut self) -> Option<I::Item<'_>> {
+        while let Some(item) = self.iter.next() {
+            if (self.predicate)(&item) {
+                return Some(item);
+            }
+        }
+        return None;
+    }
+}
diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr
new file mode 100644
index 00000000000..7ac4e5de283
--- /dev/null
+++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr
@@ -0,0 +1,12 @@
+error[E0499]: cannot borrow `*elements` as mutable more than once at a time
+  --> $DIR/iterating-updating-cursor-issue-108704.rs:40:26
+   |
+LL |         for (idx, el) in elements.iter_mut().enumerate() {
+   |                          ^^^^^^^^
+   |                          |
+   |                          `*elements` was mutably borrowed here in the previous iteration of the loop
+   |                          first borrow used here, in later iteration of loop
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs
new file mode 100644
index 00000000000..420cb73bed2
--- /dev/null
+++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs
@@ -0,0 +1,47 @@
+#![crate_type = "lib"]
+
+// An example from #108704 of the linked-list cursor-like pattern of #46859/#48001.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #108704
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+struct Root {
+    children: Vec<Node>,
+}
+
+struct Node {
+    name: String,
+    children: Vec<Node>,
+}
+
+fn merge_tree_ok(root: &mut Root, path: Vec<String>) {
+    let mut elements = &mut root.children;
+
+    for p in path.iter() {
+        for (idx, el) in elements.iter_mut().enumerate() {
+            if el.name == *p {
+                elements = &mut elements[idx].children;
+                break;
+            }
+        }
+    }
+}
+
+// NLLs fail here
+fn merge_tree_ko(root: &mut Root, path: Vec<String>) {
+    let mut elements = &mut root.children;
+
+    for p in path.iter() {
+        for (idx, el) in elements.iter_mut().enumerate() {
+            if el.name == *p {
+                elements = &mut el.children;
+                break;
+            }
+        }
+    }
+}
diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr
new file mode 100644
index 00000000000..14e1726e158
--- /dev/null
+++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr
@@ -0,0 +1,22 @@
+error[E0499]: cannot borrow `p.0` as mutable more than once at a time
+  --> $DIR/iterating-updating-cursor-issue-57165.rs:29:20
+   |
+LL |     while let Some(now) = p {
+   |                    ^^^    - first borrow used here, in later iteration of loop
+   |                    |
+   |                    `p.0` was mutably borrowed here in the previous iteration of the loop
+
+error[E0503]: cannot use `*p` because it was mutably borrowed
+  --> $DIR/iterating-updating-cursor-issue-57165.rs:29:27
+   |
+LL |     while let Some(now) = p {
+   |                    ---    ^
+   |                    |      |
+   |                    |      use of borrowed `p.0`
+   |                    |      borrow later used here
+   |                    `p.0` is borrowed here
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0499, E0503.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs
new file mode 100644
index 00000000000..63ec89146d4
--- /dev/null
+++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs
@@ -0,0 +1,44 @@
+#![crate_type = "lib"]
+
+// An example from #57165 of the linked-list cursor-like pattern of #46859/#48001.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #57165
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+struct X {
+    next: Option<Box<X>>,
+}
+
+fn no_control_flow() {
+    let mut b = Some(Box::new(X { next: None }));
+    let mut p = &mut b;
+    while let Some(now) = p {
+        p = &mut now.next;
+    }
+}
+
+// NLLs fail here
+fn conditional() {
+    let mut b = Some(Box::new(X { next: None }));
+    let mut p = &mut b;
+    while let Some(now) = p {
+        if true {
+            p = &mut now.next;
+        }
+    }
+}
+
+fn conditional_with_indirection() {
+    let mut b = Some(Box::new(X { next: None }));
+    let mut p = &mut b;
+    while let Some(now) = p {
+        if true {
+            p = &mut p.as_mut().unwrap().next;
+        }
+    }
+}
diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr
new file mode 100644
index 00000000000..bf38da566c6
--- /dev/null
+++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr
@@ -0,0 +1,18 @@
+error[E0506]: cannot assign to `*node_ref` because it is borrowed
+  --> $DIR/iterating-updating-cursor-issue-63908.rs:42:5
+   |
+LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) {
+   |                                                - let's call the lifetime of this reference `'1`
+LL |     loop {
+LL |         let next_ref = &mut node_ref.as_mut().unwrap().next;
+   |                             -------- `*node_ref` is borrowed here
+...
+LL |             node_ref = next_ref;
+   |             ------------------- assignment requires that `*node_ref` is borrowed for `'1`
+...
+LL |     *node_ref = None;
+   |     ^^^^^^^^^ `*node_ref` is assigned to here but it was already borrowed
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0506`.
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;
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr
new file mode 100644
index 00000000000..16b5d8f7148
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr
@@ -0,0 +1,17 @@
+error[E0506]: cannot assign to `*opt` because it is borrowed
+  --> $DIR/nll-problem-case-3-issue-112087.rs:23:5
+   |
+LL | fn issue_112087<'a>(opt: &'a mut Option<i32>, b: bool) -> Result<&'a mut Option<i32>, &'a mut i32> {
+   |                 -- lifetime `'a` defined here
+LL |     if let Some(v) = opt {
+   |                 - `*opt` is borrowed here
+LL |         if b {
+LL |             return Err(v);
+   |                    ------ returning this value requires that `opt.0` is borrowed for `'a`
+...
+LL |     *opt = None;
+   |     ^^^^^^^^^^^ `*opt` is assigned to here but it was already borrowed
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs
new file mode 100644
index 00000000000..d7270f6bfa7
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs
@@ -0,0 +1,25 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #112087
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+fn issue_112087<'a>(opt: &'a mut Option<i32>, b: bool) -> Result<&'a mut Option<i32>, &'a mut i32> {
+    if let Some(v) = opt {
+        if b {
+            return Err(v);
+        }
+    }
+
+    *opt = None;
+    return Ok(opt);
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr
new file mode 100644
index 00000000000..541789b7f17
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr
@@ -0,0 +1,16 @@
+error[E0506]: cannot assign to `self.status` because it is borrowed
+  --> $DIR/nll-problem-case-3-issue-123839.rs:37:9
+   |
+LL |     fn foo(self: &mut Self) -> Result<(), &str> {
+   |                  - let's call the lifetime of this reference `'1`
+LL |         self.bar()?; // rust reports this line conflicts with the next line
+   |         -----------
+   |         |
+   |         `self.status` is borrowed here
+   |         returning this value requires that `*self` is borrowed for `'1`
+LL |         self.status = 1; // and this line is the victim
+   |         ^^^^^^^^^^^^^^^ `self.status` is assigned to here but it was already borrowed
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs
new file mode 100644
index 00000000000..a738dace73d
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs
@@ -0,0 +1,40 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #123839
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+struct Foo {
+    val: i32,
+    status: i32,
+    err_str: String,
+}
+
+impl Foo {
+    fn bar(self: &mut Self) -> Result<(), &str> {
+        if self.val == 0 {
+            self.status = -1;
+            Err("val is zero")
+        } else if self.val < 0 {
+            self.status = -2;
+            self.err_str = format!("unexpected negative val {}", self.val);
+            Err(&self.err_str)
+        } else {
+            Ok(())
+        }
+    }
+    fn foo(self: &mut Self) -> Result<(), &str> {
+        self.bar()?; // rust reports this line conflicts with the next line
+        self.status = 1; // and this line is the victim
+        Ok(())
+    }
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr
new file mode 100644
index 00000000000..7c2a383e89c
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr
@@ -0,0 +1,17 @@
+error[E0502]: cannot borrow `self.field` as immutable because it is also borrowed as mutable
+  --> $DIR/nll-problem-case-3-issue-124070.rs:28:16
+   |
+LL |     fn f(&mut self) -> &str {
+   |          - let's call the lifetime of this reference `'1`
+LL |         let a = &mut self.field;
+   |                 --------------- mutable borrow occurs here
+...
+LL |             return a;
+   |                    - returning this value requires that `self.field` is borrowed for `'1`
+...
+LL |         return &self.field;
+   |                ^^^^^^^^^^^ immutable borrow occurs here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs
new file mode 100644
index 00000000000..ddf331db8bb
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs
@@ -0,0 +1,30 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #124070
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+struct S {
+    field: String,
+}
+
+impl S {
+    fn f(&mut self) -> &str {
+        let a = &mut self.field;
+
+        if false {
+            return a;
+        }
+
+        return &self.field;
+    }
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr
new file mode 100644
index 00000000000..bd5f1203f31
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr
@@ -0,0 +1,34 @@
+error[E0499]: cannot borrow `list[_]` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-124254.rs:30:5
+   |
+LL | fn find_lowest_or_first_empty_pos(list: &mut [Option<u8>]) -> &mut Option<u8> {
+   |                                         - let's call the lifetime of this reference `'1`
+LL |     let mut low_pos_val: Option<(usize, u8)> = None;
+LL |     for (idx, i) in list.iter_mut().enumerate() {
+   |                     ---- first mutable borrow occurs here
+LL |         let Some(s) = i else {
+LL |             return i;
+   |                    - returning this value requires that `*list` is borrowed for `'1`
+...
+LL |     &mut list[lowest_idx]
+   |     ^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
+
+error[E0503]: cannot use `*list` because it was mutably borrowed
+  --> $DIR/nll-problem-case-3-issue-124254.rs:30:10
+   |
+LL | fn find_lowest_or_first_empty_pos(list: &mut [Option<u8>]) -> &mut Option<u8> {
+   |                                         - let's call the lifetime of this reference `'1`
+LL |     let mut low_pos_val: Option<(usize, u8)> = None;
+LL |     for (idx, i) in list.iter_mut().enumerate() {
+   |                     ---- `*list` is borrowed here
+LL |         let Some(s) = i else {
+LL |             return i;
+   |                    - returning this value requires that `*list` is borrowed for `'1`
+...
+LL |     &mut list[lowest_idx]
+   |          ^^^^^^^^^^^^^^^^ use of borrowed `*list`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0499, E0503.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs
new file mode 100644
index 00000000000..e3bc2c2febc
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs
@@ -0,0 +1,45 @@
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #124254
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+fn find_lowest_or_first_empty_pos(list: &mut [Option<u8>]) -> &mut Option<u8> {
+    let mut low_pos_val: Option<(usize, u8)> = None;
+    for (idx, i) in list.iter_mut().enumerate() {
+        let Some(s) = i else {
+            return i;
+        };
+
+        low_pos_val = match low_pos_val {
+            Some((_oidx, oval)) if oval > *s => Some((idx, *s)),
+            Some(old) => Some(old),
+            None => Some((idx, *s)),
+        };
+    }
+    let Some((lowest_idx, _)) = low_pos_val else {
+        unreachable!("Can't have zero length list!");
+    };
+    &mut list[lowest_idx]
+}
+
+fn main() {
+    let mut list = [Some(1), Some(2), None, Some(3)];
+    let v = find_lowest_or_first_empty_pos(&mut list);
+    assert!(v.is_none());
+    assert_eq!(v as *mut _ as usize, list.as_ptr().wrapping_add(2) as usize);
+
+    let mut list = [Some(1), Some(2), Some(3), Some(0)];
+    let v = find_lowest_or_first_empty_pos(&mut list);
+    assert_eq!(v, &mut Some(0));
+    assert_eq!(v as *mut _ as usize, list.as_ptr().wrapping_add(3) as usize);
+
+    println!("pass");
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr
new file mode 100644
index 00000000000..dc38b8c127e
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr
@@ -0,0 +1,96 @@
+error[E0499]: cannot borrow `*map` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-21906.rs:26:13
+   |
+LL |   fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>(
+   |                   -- lifetime `'r` defined here
+...
+LL |       match map.get_mut(&key) {
+   |       -     --- first mutable borrow occurs here
+   |  _____|
+   | |
+LL | |         Some(value) => value,
+LL | |         None => {
+LL | |             map.insert(key, V::default());
+   | |             ^^^ second mutable borrow occurs here
+...  |
+LL | |     }
+   | |_____- returning this value requires that `*map` is borrowed for `'r`
+
+error[E0499]: cannot borrow `*map` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-21906.rs:27:13
+   |
+LL |   fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>(
+   |                   -- lifetime `'r` defined here
+...
+LL |       match map.get_mut(&key) {
+   |       -     --- first mutable borrow occurs here
+   |  _____|
+   | |
+LL | |         Some(value) => value,
+LL | |         None => {
+LL | |             map.insert(key, V::default());
+LL | |             map.get_mut(&key).unwrap()
+   | |             ^^^ second mutable borrow occurs here
+LL | |         }
+LL | |     }
+   | |_____- returning this value requires that `*map` is borrowed for `'r`
+
+error[E0499]: cannot borrow `*self` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-21906.rs:44:21
+   |
+LL |     fn two(&mut self) -> &i32 {
+   |            - let's call the lifetime of this reference `'1`
+LL |         loop {
+LL |             let k = self.one();
+   |                     ^^^^ `*self` was mutably borrowed here in the previous iteration of the loop
+LL |             if *k > 10i32 {
+LL |                 return k;
+   |                        - returning this value requires that `*self` is borrowed for `'1`
+
+error[E0502]: cannot borrow `x.data` as immutable because it is also borrowed as mutable
+  --> $DIR/nll-problem-case-3-issue-21906.rs:62:22
+   |
+LL | fn foo(x: &mut Foo) -> Option<&mut i32> {
+   |           - let's call the lifetime of this reference `'1`
+LL |     if let Some(y) = x.data.as_mut() {
+   |                      ------ mutable borrow occurs here
+LL |         return Some(y);
+   |                ------- returning this value requires that `x.data` is borrowed for `'1`
+...
+LL |     println!("{:?}", x.data);
+   |                      ^^^^^^ immutable borrow occurs here
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0499]: cannot borrow `*vec` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-21906.rs:77:9
+   |
+LL | fn f(vec: &mut Vec<u8>) -> &u8 {
+   |           - let's call the lifetime of this reference `'1`
+LL |     if let Some(n) = vec.iter_mut().find(|n| **n == 1) {
+   |                      --- first mutable borrow occurs here
+LL |         *n = 10;
+LL |         n
+   |         - returning this value requires that `*vec` is borrowed for `'1`
+LL |     } else {
+LL |         vec.push(10);
+   |         ^^^ second mutable borrow occurs here
+
+error[E0502]: cannot borrow `*vec` as immutable because it is also borrowed as mutable
+  --> $DIR/nll-problem-case-3-issue-21906.rs:78:9
+   |
+LL | fn f(vec: &mut Vec<u8>) -> &u8 {
+   |           - let's call the lifetime of this reference `'1`
+LL |     if let Some(n) = vec.iter_mut().find(|n| **n == 1) {
+   |                      --- mutable borrow occurs here
+LL |         *n = 10;
+LL |         n
+   |         - returning this value requires that `*vec` is borrowed for `'1`
+...
+LL |         vec.last().unwrap()
+   |         ^^^ immutable borrow occurs here
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0499, E0502.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs
new file mode 100644
index 00000000000..b025ea78f8b
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs
@@ -0,0 +1,85 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #21906
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+use std::collections::HashMap;
+use std::hash::Hash;
+
+fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>(
+    map: &'r mut HashMap<K, V>,
+    key: K,
+) -> &'r mut V {
+    match map.get_mut(&key) {
+        Some(value) => value,
+        None => {
+            map.insert(key, V::default());
+            map.get_mut(&key).unwrap()
+        }
+    }
+}
+
+// MCVE 1 from issue #21906
+struct A {
+    a: i32,
+}
+
+impl A {
+    fn one(&mut self) -> &i32 {
+        self.a = 10;
+        &self.a
+    }
+    fn two(&mut self) -> &i32 {
+        loop {
+            let k = self.one();
+            if *k > 10i32 {
+                return k;
+            }
+        }
+    }
+}
+
+// MCVE 2
+struct Foo {
+    data: Option<i32>,
+}
+
+fn foo(x: &mut Foo) -> Option<&mut i32> {
+    if let Some(y) = x.data.as_mut() {
+        return Some(y);
+    }
+
+    println!("{:?}", x.data);
+    None
+}
+
+fn mcve2() {
+    let mut x = Foo { data: Some(1) };
+    foo(&mut x);
+}
+
+// MCVE 3
+fn f(vec: &mut Vec<u8>) -> &u8 {
+    if let Some(n) = vec.iter_mut().find(|n| **n == 1) {
+        *n = 10;
+        n
+    } else {
+        vec.push(10);
+        vec.last().unwrap()
+    }
+}
+
+fn mcve3() {
+    let mut vec = vec![1, 2, 3];
+    f(&mut vec);
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr
new file mode 100644
index 00000000000..9a740a0edc7
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr
@@ -0,0 +1,18 @@
+error[E0502]: cannot borrow `*queue` as mutable because it is also borrowed as immutable
+  --> $DIR/nll-problem-case-3-issue-51526.rs:26:9
+   |
+LL | fn next(queue: &mut VecDeque<u32>, above: u32) -> Option<&u32> {
+   |                - let's call the lifetime of this reference `'1`
+...
+LL |             let next = queue.front()?;
+   |                        ----- immutable borrow occurs here
+...
+LL |         queue.pop_front();
+   |         ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+...
+LL |     Some(result)
+   |     ------------ returning this value requires that `*queue` is borrowed for `'1`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs
new file mode 100644
index 00000000000..3cf211586b2
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs
@@ -0,0 +1,30 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #51526
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+use std::collections::VecDeque;
+
+fn next(queue: &mut VecDeque<u32>, above: u32) -> Option<&u32> {
+    let result = loop {
+        {
+            let next = queue.front()?;
+            if *next > above {
+                break next;
+            }
+        }
+        queue.pop_front();
+    };
+
+    Some(result)
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr
new file mode 100644
index 00000000000..c6a0e1b282f
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr
@@ -0,0 +1,15 @@
+error[E0499]: cannot borrow `*o` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-51545.rs:17:17
+   |
+LL | fn borrow(o: &mut Option<i32>) -> Option<&mut i32> {
+   |              - let's call the lifetime of this reference `'1`
+LL |     match o.as_mut() {
+   |           - first mutable borrow occurs here
+LL |         Some(i) => Some(i),
+   |                    ------- returning this value requires that `*o` is borrowed for `'1`
+LL |         None => o.as_mut(),
+   |                 ^ second mutable borrow occurs here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs
new file mode 100644
index 00000000000..786a8b564b9
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs
@@ -0,0 +1,28 @@
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #51545
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+fn borrow(o: &mut Option<i32>) -> Option<&mut i32> {
+    match o.as_mut() {
+        Some(i) => Some(i),
+        None => o.as_mut(),
+    }
+}
+
+fn main() {
+    let mut o: Option<i32> = Some(1i32);
+
+    let x = match o.as_mut() {
+        Some(i) => Some(i),
+        None => o.as_mut(),
+    };
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr
new file mode 100644
index 00000000000..fd6fa7632d5
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr
@@ -0,0 +1,16 @@
+error[E0499]: cannot borrow `*x` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-54663.rs:20:9
+   |
+LL | fn foo(x: &mut u8) -> Option<&u8> {
+   |           - let's call the lifetime of this reference `'1`
+LL |     if let Some(y) = bar(x) {
+   |                          - first mutable borrow occurs here
+LL |         return Some(y);
+   |                ------- returning this value requires that `*x` is borrowed for `'1`
+LL |     }
+LL |     bar(x)
+   |         ^ second mutable borrow occurs here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs
new file mode 100644
index 00000000000..b4d571fb9c7
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs
@@ -0,0 +1,25 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #54663
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+fn foo(x: &mut u8) -> Option<&u8> {
+    if let Some(y) = bar(x) {
+        return Some(y);
+    }
+    bar(x)
+}
+
+fn bar(x: &mut u8) -> Option<&u8> {
+    Some(x)
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr
new file mode 100644
index 00000000000..53002892df1
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr
@@ -0,0 +1,112 @@
+error[E0503]: cannot use `list.0` because it was mutably borrowed
+  --> $DIR/nll-problem-case-3-issue-58787.rs:34:11
+   |
+LL |         Some(ref mut d) => {
+   |              --------- `list.0.0` is borrowed here
+...
+LL |     match list.0 {
+   |           ^^^^^^
+   |           |
+   |           use of borrowed `list.0.0`
+   |           borrow later used here
+
+error[E0499]: cannot borrow `list.0.0` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-58787.rs:35:14
+   |
+LL |         Some(ref mut d) => {
+   |              --------- first mutable borrow occurs here
+...
+LL |         Some(ref mut d) => {
+   |              ^^^^^^^^^
+   |              |
+   |              second mutable borrow occurs here
+   |              first borrow later used here
+
+error[E0503]: cannot use `list.0` because it was mutably borrowed
+  --> $DIR/nll-problem-case-3-issue-58787.rs:41:11
+   |
+LL |         Some(ref mut d) => {
+   |              --------- `list.0.0` is borrowed here
+...
+LL |     match list {
+   |           ^^^^
+   |           |
+   |           use of borrowed `list.0.0`
+   |           borrow later used here
+
+error[E0499]: cannot borrow `list.0.0` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-58787.rs:42:19
+   |
+LL |         Some(ref mut d) => {
+   |              --------- first mutable borrow occurs here
+...
+LL |         List(Some(d)) => {
+   |                   ^
+   |                   |
+   |                   second mutable borrow occurs here
+   |                   first borrow later used here
+
+error[E0503]: cannot use `list.0` because it was mutably borrowed
+  --> $DIR/nll-problem-case-3-issue-58787.rs:50:11
+   |
+LL |         List(Some(d)) => {
+   |                   - `list.0.0` is borrowed here
+...
+LL |     match list {
+   |           ^^^^
+   |           |
+   |           use of borrowed `list.0.0`
+   |           borrow later used here
+
+error[E0499]: cannot borrow `list.0.0` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-58787.rs:51:19
+   |
+LL |         List(Some(d)) => {
+   |                   - first mutable borrow occurs here
+...
+LL |         List(Some(d)) => {
+   |                   ^
+   |                   |
+   |                   second mutable borrow occurs here
+   |                   first borrow later used here
+
+error[E0499]: cannot borrow `list.0` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-58787.rs:57:11
+   |
+LL |         List(Some(d)) => {
+   |                   - first mutable borrow occurs here
+...
+LL |     match &mut list.0 {
+   |           ^^^^^^^^^^^
+   |           |
+   |           second mutable borrow occurs here
+   |           first borrow later used here
+
+error[E0499]: cannot borrow `list.0` as mutable more than once at a time
+  --> $DIR/nll-problem-case-3-issue-58787.rs:66:11
+   |
+LL |     match &mut list.0 {
+   |           ----------- first mutable borrow occurs here
+...
+LL |     match &mut list.0 {
+   |           ^^^^^^^^^^^
+   |           |
+   |           second mutable borrow occurs here
+   |           first borrow later used here
+
+error[E0506]: cannot assign to `list.0` because it is borrowed
+  --> $DIR/nll-problem-case-3-issue-58787.rs:73:5
+   |
+LL |     match &mut list.0 {
+   |           ----------- `list.0` is borrowed here
+...
+LL |     list.0 = None;
+   |     ^^^^^^
+   |     |
+   |     `list.0` is assigned to here but it was already borrowed
+   |     borrow later used here
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0499, E0503, E0506.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs
new file mode 100644
index 00000000000..75552e24219
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs
@@ -0,0 +1,74 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #58787
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+struct Node {
+    rest: List,
+}
+
+struct List(Option<Box<Node>>);
+
+fn issue_58787(arg: &mut List) {
+    let mut list = arg;
+
+    match list.0 {
+        Some(ref mut d) => {
+            if true {
+                list = &mut d.rest;
+            }
+        }
+        None => (),
+    }
+
+    match list.0 {
+        Some(ref mut d) => {
+            list = &mut d.rest;
+        }
+        None => (),
+    }
+
+    match list {
+        List(Some(d)) => {
+            if true {
+                list = &mut d.rest;
+            }
+        }
+        List(None) => (),
+    }
+
+    match list {
+        List(Some(d)) => {
+            list = &mut d.rest;
+        }
+        List(None) => (),
+    }
+
+    match &mut list.0 {
+        Some(d) => {
+            if true {
+                list = &mut d.rest;
+            }
+        }
+        None => (),
+    }
+
+    match &mut list.0 {
+        Some(d) => {
+            list = &mut d.rest;
+        }
+        None => (),
+    }
+
+    list.0 = None;
+}
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr
new file mode 100644
index 00000000000..212355790bf
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr
@@ -0,0 +1,17 @@
+error[E0505]: cannot move out of value because it is borrowed
+  --> $DIR/nll-problem-case-3-issue-68934.rs:35:14
+   |
+LL |     fn deep_fetch(&mut self, value: Either<A, B>) -> Result<&mut Self, (&mut Self, Either<A, B>)> {
+   |                   - let's call the lifetime of this reference `'1`
+LL |         match (self, value) {
+LL |             (Tree::ABranch(ref mut a, ref v), Either::Left(vv)) if v > &vv => {
+   |                            --------- borrow of value occurs here
+LL |                 a.deep_fetch(Either::Left(vv))
+   |                 ------------------------------ returning this value requires that borrow lasts for `'1`
+...
+LL |             (this, _v) => Err((this, _v)),
+   |              ^^^^ move out of value occurs here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs
new file mode 100644
index 00000000000..ba941510116
--- /dev/null
+++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs
@@ -0,0 +1,38 @@
+#![crate_type = "lib"]
+
+// This is part of a collection of regression tests related to the NLL problem case 3 that was
+// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are
+// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does
+// handle them, as does the datalog implementation.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [nll] known-bug: #68934
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] check-pass
+//@ [legacy] compile-flags: -Z polonius=legacy
+
+enum Either<A, B> {
+    Left(A),
+    Right(B),
+}
+
+enum Tree<'a, A, B> {
+    ALeaf(A),
+    BLeaf(B),
+    ABranch(&'a mut Tree<'a, A, B>, A),
+    BBranch(&'a mut Tree<'a, A, B>, B),
+}
+
+impl<'a, A: PartialOrd, B> Tree<'a, A, B> {
+    fn deep_fetch(&mut self, value: Either<A, B>) -> Result<&mut Self, (&mut Self, Either<A, B>)> {
+        match (self, value) {
+            (Tree::ABranch(ref mut a, ref v), Either::Left(vv)) if v > &vv => {
+                a.deep_fetch(Either::Left(vv))
+            }
+
+            (this, _v) => Err((this, _v)),
+        }
+    }
+}