, polarity:Positive), bound_vars: [] } - = note: Binder { value: TraitClause(
, polarity:Positive), bound_vars: [] }
- = note: Binder { value: TraitClause(< as std::ops::Deref>, polarity:Positive), bound_vars: [] }
- = note: Binder { value: TraitClause(< as std::marker::Sized>, polarity:Positive), bound_vars: [] }
-
-error: aborting due to 3 previous errors
-
diff --git a/tests/ui/nll/polonius/boring-local-drop-liveness.nll.stderr b/tests/ui/nll/polonius/boring-local-drop-liveness.nll.stderr
new file mode 100644
index 0000000000000..1618679c8b2d4
--- /dev/null
+++ b/tests/ui/nll/polonius/boring-local-drop-liveness.nll.stderr
@@ -0,0 +1,32 @@
+error[E0506]: cannot assign to `*x` because it is borrowed
+ --> $DIR/boring-local-drop-liveness.rs:28:5
+ |
+LL | fn assigning_under_a_live_destructor<'a>(
+ | -- lifetime `'a` defined here
+...
+LL | *slot = Some(d.0);
+ | ----------------- assignment requires that `*x` is borrowed for `'a`
+LL | d = D(&*x);
+ | --- `*x` is borrowed here
+LL | *x = String::new();
+ | ^^ `*x` is assigned to here but it was already borrowed
+
+error[E0597]: `local` does not live long enough
+ --> $DIR/boring-local-drop-liveness.rs:35:11
+ |
+LL | fn dropping_under_a_live_destructor<'a>(x: &'a String, slot: &mut Option<&'a String>) {
+ | -- lifetime `'a` defined here
+LL | let mut d = D(x);
+LL | *slot = Some(d.0);
+ | ----------------- assignment requires that `local` is borrowed for `'a`
+LL | let local = String::from("gone");
+ | ----- binding `local` declared here
+LL | d = D(&local);
+ | ^^^^^^ borrowed value does not live long enough
+LL | }
+ | - `local` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0506, E0597.
+For more information about an error, try `rustc --explain E0506`.
diff --git a/tests/ui/nll/polonius/boring-local-drop-liveness.polonius_next.stderr b/tests/ui/nll/polonius/boring-local-drop-liveness.polonius_next.stderr
new file mode 100644
index 0000000000000..1618679c8b2d4
--- /dev/null
+++ b/tests/ui/nll/polonius/boring-local-drop-liveness.polonius_next.stderr
@@ -0,0 +1,32 @@
+error[E0506]: cannot assign to `*x` because it is borrowed
+ --> $DIR/boring-local-drop-liveness.rs:28:5
+ |
+LL | fn assigning_under_a_live_destructor<'a>(
+ | -- lifetime `'a` defined here
+...
+LL | *slot = Some(d.0);
+ | ----------------- assignment requires that `*x` is borrowed for `'a`
+LL | d = D(&*x);
+ | --- `*x` is borrowed here
+LL | *x = String::new();
+ | ^^ `*x` is assigned to here but it was already borrowed
+
+error[E0597]: `local` does not live long enough
+ --> $DIR/boring-local-drop-liveness.rs:35:11
+ |
+LL | fn dropping_under_a_live_destructor<'a>(x: &'a String, slot: &mut Option<&'a String>) {
+ | -- lifetime `'a` defined here
+LL | let mut d = D(x);
+LL | *slot = Some(d.0);
+ | ----------------- assignment requires that `local` is borrowed for `'a`
+LL | let local = String::from("gone");
+ | ----- binding `local` declared here
+LL | d = D(&local);
+ | ^^^^^^ borrowed value does not live long enough
+LL | }
+ | - `local` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0506, E0597.
+For more information about an error, try `rustc --explain E0506`.
diff --git a/tests/ui/nll/polonius/boring-local-drop-liveness.rs b/tests/ui/nll/polonius/boring-local-drop-liveness.rs
new file mode 100644
index 0000000000000..d473a2faeb5c5
--- /dev/null
+++ b/tests/ui/nll/polonius/boring-local-drop-liveness.rs
@@ -0,0 +1,38 @@
+// Polonius requires liveness for some locals that NLL leaves "boring": locals
+// containing some region that outlives a universal region but is not universal itself.
+//
+// This test checks that we correctly compute liveness for NLL-boring locals that
+// are live only because of their drop.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius_next
+//@ [nll] compile-flags: -Zpolonius=off
+//@ [polonius_next] compile-flags: -Zpolonius=next
+
+struct D<'a>(&'a String);
+
+impl<'a> Drop for D<'a> {
+ fn drop(&mut self) {
+ println!("{}", self.0);
+ }
+}
+
+fn assigning_under_a_live_destructor<'a>(
+ x: &'a mut String,
+ slot: &mut Option<&'a String>,
+ y: &'a String,
+) {
+ let mut d = D(y);
+ *slot = Some(d.0);
+ d = D(&*x);
+ *x = String::new(); //~ ERROR cannot assign to `*x` because it is borrowed
+}
+
+fn dropping_under_a_live_destructor<'a>(x: &'a String, slot: &mut Option<&'a String>) {
+ let mut d = D(x);
+ *slot = Some(d.0);
+ let local = String::from("gone");
+ d = D(&local); //~ ERROR `local` does not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/nll/polonius/boring-local-liveness.nll.stderr b/tests/ui/nll/polonius/boring-local-liveness.nll.stderr
new file mode 100644
index 0000000000000..5d5c46a97e946
--- /dev/null
+++ b/tests/ui/nll/polonius/boring-local-liveness.nll.stderr
@@ -0,0 +1,30 @@
+error[E0506]: cannot assign to `*x` because it is borrowed
+ --> $DIR/boring-local-liveness.rs:22:5
+ |
+LL | fn assigning_into_a_slot<'a>(x: &'a mut u32, slot: &mut Option