Auto merge of #112145 - wesleywiser:backport_112070, r=Mark-Simulacrum
Backport of #112070
Backports #112070 to stable
r? `@Mark-Simulacrum`
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index 9e9f0b4..6deb4e3 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -50,7 +50,6 @@
PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 375eca1..2f10e30 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -775,9 +775,10 @@
ty::Invariant
}
PlaceContext::NonMutatingUse(
- Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf
- | Projection,
- ) => ty::Covariant,
+ Inspect | Copy | Move | SharedBorrow | ShallowBorrow | AddressOf | Projection
+ ) => {
+ ty::Covariant
+ },
PlaceContext::NonUse(AscribeUserTy) => ty::Covariant,
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 115a410..f43f1d6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -232,7 +232,6 @@
| PlaceContext::NonMutatingUse(
NonMutatingUseContext::Inspect
| NonMutatingUseContext::SharedBorrow
- | NonMutatingUseContext::UniqueBorrow
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::AddressOf
| NonMutatingUseContext::Projection,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 9dad947..55080d9 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -412,9 +412,7 @@
BorrowKind::Shallow => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
}
- BorrowKind::Unique => {
- PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
- }
+ BorrowKind::Unique => PlaceContext::MutatingUse(MutatingUseContext::Borrow),
BorrowKind::Mut { .. } => {
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
}
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 135889d..93800d4 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -220,6 +220,11 @@
/// immutable, but not aliasable. This solves the problem. For
/// simplicity, we don't give users the way to express this
/// borrow, it's just used when translating closures.
+ ///
+ // FIXME(#112072): This is wrong. Unique borrows are mutable borrows except
+ // that they do not require their pointee to be marked as a mutable.
+ // They should still be treated as mutable borrows in every other way,
+ // e.g. for variance or overlap checking.
Unique,
/// Data is mutable and not aliasable.
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 0a9fcd8..caa5edc 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -640,8 +640,8 @@
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
NonMutatingUseContext::ShallowBorrow
),
- BorrowKind::Unique => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::UniqueBorrow
+ BorrowKind::Unique => PlaceContext::MutatingUse(
+ MutatingUseContext::Borrow
),
BorrowKind::Mut { .. } =>
PlaceContext::MutatingUse(MutatingUseContext::Borrow),
@@ -1247,8 +1247,6 @@
SharedBorrow,
/// Shallow borrow.
ShallowBorrow,
- /// Unique borrow.
- UniqueBorrow,
/// AddressOf for *const pointer.
AddressOf,
/// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
@@ -1324,9 +1322,7 @@
matches!(
self,
PlaceContext::NonMutatingUse(
- NonMutatingUseContext::SharedBorrow
- | NonMutatingUseContext::ShallowBorrow
- | NonMutatingUseContext::UniqueBorrow
+ NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::ShallowBorrow
) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
)
}
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index bc67aa4..1309ea5 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -198,8 +198,7 @@
| NonMutatingUseContext::Inspect
| NonMutatingUseContext::Move
| NonMutatingUseContext::ShallowBorrow
- | NonMutatingUseContext::SharedBorrow
- | NonMutatingUseContext::UniqueBorrow,
+ | NonMutatingUseContext::SharedBorrow,
) => Some(DefUse::Use),
PlaceContext::MutatingUse(MutatingUseContext::Projection)
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index c0146e3..1bb4534 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -822,7 +822,6 @@
// mutation.
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
| NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
- | NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
| NonMutatingUse(NonMutatingUseContext::AddressOf)
| MutatingUse(MutatingUseContext::Borrow)
| MutatingUse(MutatingUseContext::AddressOf) => {
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index c155048..b571215 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -131,7 +131,6 @@
PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::ShallowBorrow
- | NonMutatingUseContext::UniqueBorrow
| NonMutatingUseContext::AddressOf,
) => true,
// For debuginfo, merging locals is ok.
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs
new file mode 100644
index 0000000..f21ef43
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs
@@ -0,0 +1,18 @@
+// edition:2021
+
+// regression test for #112056
+
+fn extend_lifetime<'a, 'b>(x: &mut (&'a str,), y: &'b str) {
+ let mut closure = |input| x.0 = input;
+ //~^ ERROR: lifetime may not live long enough
+ closure(y);
+}
+
+fn main() {
+ let mut tuple = ("static",);
+ {
+ let x = String::from("temporary");
+ extend_lifetime(&mut tuple, &x);
+ }
+ println!("{}", tuple.0);
+}
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr
new file mode 100644
index 0000000..7308232
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+ --> $DIR/unique-borrows-are-invariant-1.rs:6:31
+ |
+LL | fn extend_lifetime<'a, 'b>(x: &mut (&'a str,), y: &'b str) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let mut closure = |input| x.0 = input;
+ | ^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs
new file mode 100644
index 0000000..dd9d986
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs
@@ -0,0 +1,31 @@
+// edition:2021
+
+// regression test for #112056
+
+struct Spooky<'b> {
+ owned: Option<&'static u32>,
+ borrowed: &'b &'static u32,
+}
+
+impl<'b> Spooky<'b> {
+ fn create_self_reference<'a>(&'a mut self) {
+ let mut closure = || {
+ if let Some(owned) = &self.owned {
+ let borrow: &'a &'static u32 = owned;
+ self.borrowed = borrow;
+ //~^ ERROR: lifetime may not live long enough
+ }
+ };
+ closure();
+ }
+}
+
+fn main() {
+ let mut spooky: Spooky<'static> = Spooky {
+ owned: Some(&1),
+ borrowed: &&1,
+ };
+ spooky.create_self_reference();
+ spooky.owned = None;
+ println!("{}", **spooky.borrowed);
+}
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr
new file mode 100644
index 0000000..66ba0fe
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/unique-borrows-are-invariant-2.rs:15:17
+ |
+LL | impl<'b> Spooky<'b> {
+ | -- lifetime `'b` defined here
+LL | fn create_self_reference<'a>(&'a mut self) {
+ | -- lifetime `'a` defined here
+...
+LL | self.borrowed = borrow;
+ | ^^^^^^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+