Skip to content

Commit

Permalink
Auto merge of #112145 - wesleywiser:backport_112070, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
Backport of #112070

Backports #112070 to stable

r? `@Mark-Simulacrum`
  • Loading branch information
bors committed May 31, 2023
2 parents d332def + 4930c02 commit 90c5418
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 19 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_borrowck/src/def_use.rs
Expand Up @@ -50,7 +50,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |

PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Expand Up @@ -775,9 +775,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
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,
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/analyze.rs
Expand Up @@ -232,7 +232,6 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
| PlaceContext::NonMutatingUse(
NonMutatingUseContext::Inspect
| NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::UniqueBorrow
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::AddressOf
| NonMutatingUseContext::Projection,
Expand Down
Expand Up @@ -412,9 +412,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
BorrowKind::Shallow => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
}
BorrowKind::Unique => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
}
BorrowKind::Unique => PlaceContext::MutatingUse(MutatingUseContext::Borrow),
BorrowKind::Mut { .. } => {
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/mir/syntax.rs
Expand Up @@ -220,6 +220,11 @@ pub enum BorrowKind {
/// 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.
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_middle/src/mir/visit.rs
Expand Up @@ -640,8 +640,8 @@ macro_rules! make_mir_visitor {
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
NonMutatingUseContext::ShallowBorrow
),
BorrowKind::Unique => PlaceContext::NonMutatingUse(
NonMutatingUseContext::UniqueBorrow
BorrowKind::Unique => PlaceContext::MutatingUse(
MutatingUseContext::Borrow
),
BorrowKind::Mut { .. } =>
PlaceContext::MutatingUse(MutatingUseContext::Borrow),
Expand Down Expand Up @@ -1247,8 +1247,6 @@ pub enum NonMutatingUseContext {
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.
Expand Down Expand Up @@ -1324,9 +1322,7 @@ impl PlaceContext {
matches!(
self,
PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::UniqueBorrow
NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::ShallowBorrow
) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
)
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_dataflow/src/impls/liveness.rs
Expand Up @@ -198,8 +198,7 @@ impl DefUse {
| NonMutatingUseContext::Inspect
| NonMutatingUseContext::Move
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::UniqueBorrow,
| NonMutatingUseContext::SharedBorrow,
) => Some(DefUse::Use),

PlaceContext::MutatingUse(MutatingUseContext::Projection)
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_mir_transform/src/const_prop.rs
Expand Up @@ -822,7 +822,6 @@ impl Visitor<'_> for CanConstProp {
// mutation.
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
| NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
| NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
| NonMutatingUse(NonMutatingUseContext::AddressOf)
| MutatingUse(MutatingUseContext::Borrow)
| MutatingUse(MutatingUseContext::AddressOf) => {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_mir_transform/src/copy_prop.rs
Expand Up @@ -131,7 +131,6 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::UniqueBorrow
| NonMutatingUseContext::AddressOf,
) => true,
// For debuginfo, merging locals is ok.
Expand Down
@@ -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);
}
@@ -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

@@ -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);
}
@@ -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

0 comments on commit 90c5418

Please sign in to comment.