Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change BorrowKind::Unique to be a mutating PlaceContext #112070

Merged
merged 3 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion compiler/rustc_borrowck/src/def_use.rs
Original file line number Diff line number Diff line change
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) |

// `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
// contain dangling references.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,8 +766,8 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
PlaceContext::MutatingUse(_) => ty::Invariant,
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
PlaceContext::NonMutatingUse(
Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow
| AddressOf | Projection,
Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | AddressOf
| Projection,
) => ty::Covariant,
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -650,8 +650,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 @@ -1265,8 +1265,6 @@ pub enum NonMutatingUseContext {
SharedBorrow,
/// Shallow borrow.
ShallowBorrow,
/// Unique borrow.
UniqueBorrow,
/// AddressOf for *const pointer.
AddressOf,
/// PlaceMention statement.
Expand Down Expand Up @@ -1345,9 +1343,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
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ impl DefUse {
| NonMutatingUseContext::Move
| NonMutatingUseContext::PlaceMention
| 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
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,6 @@ impl<'tcx> Visitor<'tcx> 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
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,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
1 change: 0 additions & 1 deletion compiler/rustc_mir_transform/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::UniqueBorrow
| NonMutatingUseContext::AddressOf,
)
| PlaceContext::MutatingUse(_) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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