Skip to content
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
14 changes: 10 additions & 4 deletions compiler/rustc_mir_build/src/builder/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2694,8 +2694,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ScheduleDrops::Yes,
);

let rvalue =
Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source);
let rvalue = Rvalue::Ref(
re_erased,
util::ref_pat_borrow_kind(pinnedness, mutbl),
binding.source,
);
let rvalue = match pinnedness {
ty::Pinnedness::Not => rvalue,
ty::Pinnedness::Pinned => {
Expand Down Expand Up @@ -2739,8 +2742,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let rvalue = match binding.binding_mode.0 {
ByRef::No => Rvalue::Use(self.consume_by_copy_or_move(binding.source)),
ByRef::Yes(pinnedness, mutbl) => {
let rvalue =
Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source);
let rvalue = Rvalue::Ref(
re_erased,
util::ref_pat_borrow_kind(pinnedness, mutbl),
binding.source,
);
match pinnedness {
ty::Pinnedness::Not => rvalue,
ty::Pinnedness::Pinned => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/builder/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Mutability::Not => (LangItem::Deref, sym::deref),
Mutability::Mut => (LangItem::DerefMut, sym::deref_mut),
};
let borrow_kind = super::util::ref_pat_borrow_kind(mutability);
let borrow_kind = super::util::ref_pat_borrow_kind(ty::Pinnedness::Not, mutability);
let source_info = self.source_info(span);
let re_erased = self.tcx.lifetimes.re_erased;
let trait_item = self.tcx.require_lang_item(trait_item, span);
Expand Down
16 changes: 11 additions & 5 deletions compiler/rustc_mir_build/src/builder/matches/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_middle::mir::*;
use rustc_middle::ty::Ty;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
use tracing::debug;

Expand Down Expand Up @@ -228,9 +228,15 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
}

#[must_use]
pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind {
match ref_mutability {
Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
Mutability::Not => BorrowKind::Shared,
pub(crate) fn ref_pat_borrow_kind(
pinnedness: ty::Pinnedness,
ref_mutability: Mutability,
) -> BorrowKind {
match pinnedness {
ty::Pinnedness::Pinned => BorrowKind::Pinned(ref_mutability, PinBorrowKind::Persistent),
ty::Pinnedness::Not => match ref_mutability {
Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
Mutability::Not => BorrowKind::Shared,
},
}
}
42 changes: 42 additions & 0 deletions tests/ui/pin-ergonomics/borrow-pinned-projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ fn mutable_borrow_of_pinned_projection() {
//~^ ERROR cannot borrow `pair.0` as mutable because it is pinned
}

fn ref_pin_pattern_mutable_borrow_of_pinned_projection() {
let mut pair = (Foo::default(), Foo::default());

{
let ref pin mut _pin = pair.0;
}

let _other = &mut pair.1;
let _borrow = &mut pair.0;
//~^ ERROR cannot borrow `pair.0` as mutable because it is pinned
}

fn move_of_pinned_projection() {
let mut pair = (Foo::default(), Foo::default());

Expand All @@ -33,6 +45,18 @@ fn move_of_pinned_projection() {
//~^ ERROR cannot move out of `pair.0` because it is pinned
}

fn ref_pin_pattern_move_of_pinned_projection() {
let mut pair = (Foo::default(), Foo::default());

{
let ref pin mut _pin = pair.0;
}

let _other = &mut pair.1;
let _moved = pair.0;
//~^ ERROR cannot move out of `pair.0` because it is pinned
}

#[pin_v2]
struct ContainsUnpinField {
field: String,
Expand All @@ -48,6 +72,15 @@ fn pinned_parent_still_blocks_unpin_field_move(mut value: ContainsUnpinField) {
//~^ ERROR cannot move out of `value.field` because it is pinned
}

fn ref_pin_pattern_parent_still_blocks_unpin_field_move(mut value: ContainsUnpinField) {
{
let ref pin mut _pin = value;
}

let _moved = value.field;
//~^ ERROR cannot move out of `value.field` because it is pinned
}

fn pinned_parent_still_blocks_unpin_field_mut_borrow(mut value: ContainsUnpinField) {
{
let _ = &pin mut value;
Expand All @@ -57,4 +90,13 @@ fn pinned_parent_still_blocks_unpin_field_mut_borrow(mut value: ContainsUnpinFie
//~^ ERROR cannot borrow `value.field` as mutable because it is pinned
}

fn ref_pin_pattern_parent_still_blocks_unpin_field_mut_borrow(mut value: ContainsUnpinField) {
{
let ref pin mut _pin = value;
}

let _ = &mut value.field;
//~^ ERROR cannot borrow `value.field` as mutable because it is pinned
}

fn main() {}
44 changes: 40 additions & 4 deletions tests/ui/pin-ergonomics/borrow-pinned-projection.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,68 @@ LL | let _pin = &pin mut pair.0;
LL | let _borrow = &mut pair.0;
| ^^^^^^^^^^^ borrow of `pair.0` as mutable occurs here

error: cannot borrow `pair.0` as mutable because it is pinned
--> $DIR/borrow-pinned-projection.rs:32:19
|
LL | let ref pin mut _pin = pair.0;
| ---------------- pin of `pair.0` occurs here
...
LL | let _borrow = &mut pair.0;
| ^^^^^^^^^^^ borrow of `pair.0` as mutable occurs here

error: cannot move out of `pair.0` because it is pinned
--> $DIR/borrow-pinned-projection.rs:32:18
--> $DIR/borrow-pinned-projection.rs:44:18
|
LL | let _pin = &pin mut pair.0;
| --------------- pin of `pair.0` occurs here
...
LL | let _moved = pair.0;
| ^^^^^^ move out of `pair.0` occurs here

error: cannot move out of `pair.0` because it is pinned
--> $DIR/borrow-pinned-projection.rs:56:18
|
LL | let ref pin mut _pin = pair.0;
| ---------------- pin of `pair.0` occurs here
...
LL | let _moved = pair.0;
| ^^^^^^ move out of `pair.0` occurs here

error: cannot move out of `value.field` because it is pinned
--> $DIR/borrow-pinned-projection.rs:47:18
--> $DIR/borrow-pinned-projection.rs:71:18
|
LL | let _ = &pin mut value;
| -------------- pin of `value` occurs here
...
LL | let _moved = value.field;
| ^^^^^^^^^^^ move out of `value.field` occurs here

error: cannot move out of `value.field` because it is pinned
--> $DIR/borrow-pinned-projection.rs:80:18
|
LL | let ref pin mut _pin = value;
| ---------------- pin of `value` occurs here
...
LL | let _moved = value.field;
| ^^^^^^^^^^^ move out of `value.field` occurs here

error: cannot borrow `value.field` as mutable because it is pinned
--> $DIR/borrow-pinned-projection.rs:56:13
--> $DIR/borrow-pinned-projection.rs:89:13
|
LL | let _ = &pin mut value;
| -------------- pin of `value` occurs here
...
LL | let _ = &mut value.field;
| ^^^^^^^^^^^^^^^^ borrow of `value.field` as mutable occurs here

error: aborting due to 4 previous errors
error: cannot borrow `value.field` as mutable because it is pinned
--> $DIR/borrow-pinned-projection.rs:98:13
|
LL | let ref pin mut _pin = value;
| ---------------- pin of `value` occurs here
...
LL | let _ = &mut value.field;
| ^^^^^^^^^^^^^^^^ borrow of `value.field` as mutable occurs here

error: aborting due to 8 previous errors

28 changes: 23 additions & 5 deletions tests/ui/pin-ergonomics/borrow-unpin.pinned.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,26 @@ LL | struct Foo(PhantomPinned);
LL | let x = &pin const foo; // ok
| --- you could clone this value

error: cannot move out of `foo` because it is pinned
--> $DIR/borrow-unpin.rs:65:14
|
LL | let ref pin mut _x = foo;
| -------------- pin of `foo` occurs here
LL | }
LL | foo_move(foo);
| ^^^ move out of `foo` occurs here

error: cannot borrow `foo` as mutable because it is pinned
--> $DIR/borrow-unpin.rs:73:13
|
LL | let ref pin mut _x = foo;
| -------------- pin of `foo` occurs here
LL | }
LL | foo_mut(&mut foo);
| ^^^^^^^^ borrow of `foo` as mutable occurs here

error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
--> $DIR/borrow-unpin.rs:67:13
--> $DIR/borrow-unpin.rs:83:13
|
LL | let x = &pin mut foo; // ok
| ------------ mutable borrow occurs here
Expand All @@ -96,7 +114,7 @@ LL | foo_pin_mut(x);
| - mutable borrow later used here

error[E0499]: cannot borrow `foo` as mutable more than once at a time
--> $DIR/borrow-unpin.rs:89:17
--> $DIR/borrow-unpin.rs:105:17
|
LL | let x = &pin mut foo; // ok
| ------------ first mutable borrow occurs here
Expand All @@ -106,7 +124,7 @@ LL | foo_pin_mut(x);
| - first borrow later used here

error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
--> $DIR/borrow-unpin.rs:100:17
--> $DIR/borrow-unpin.rs:116:17
|
LL | let x = &pin const foo; // ok
| -------------- immutable borrow occurs here
Expand All @@ -116,7 +134,7 @@ LL | foo_pin_ref(x);
| - immutable borrow later used here

error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
--> $DIR/borrow-unpin.rs:111:17
--> $DIR/borrow-unpin.rs:127:17
|
LL | let x = &pin mut foo; // ok
| ------------ mutable borrow occurs here
Expand All @@ -125,7 +143,7 @@ LL | foo_pin_ref(&pin const foo);
LL | foo_pin_mut(x);
| - mutable borrow later used here

error: aborting due to 10 previous errors
error: aborting due to 12 previous errors

Some errors have detailed explanations: E0499, E0502, E0505.
For more information about an error, try `rustc --explain E0499`.
16 changes: 16 additions & 0 deletions tests/ui/pin-ergonomics/borrow-unpin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ fn pin_ref_then_move() {
foo_pin_ref(x);
}

fn ref_pin_mut_then_move() {
let mut foo = Foo::default();
{
let ref pin mut _x = foo;
}
foo_move(foo); //[pinned]~ ERROR cannot move out of `foo` because it is pinned
}

fn ref_pin_mut_then_mut_borrow() {
let mut foo = Foo::default();
{
let ref pin mut _x = foo;
}
foo_mut(&mut foo); //[pinned]~ ERROR cannot borrow `foo` as mutable because it is pinned
}

fn pin_mut_then_ref() {
let mut foo = Foo::default();
foo_pin_mut(&pin mut foo); // ok
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/pin-ergonomics/borrow-unpin.unpin.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ LL | let x = &pin const foo; // ok
| --- you could clone this value

error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
--> $DIR/borrow-unpin.rs:67:13
--> $DIR/borrow-unpin.rs:83:13
|
LL | let x = &pin mut foo; // ok
| ------------ mutable borrow occurs here
Expand All @@ -72,7 +72,7 @@ LL | foo_pin_mut(x);
| - mutable borrow later used here

error[E0499]: cannot borrow `foo` as mutable more than once at a time
--> $DIR/borrow-unpin.rs:89:17
--> $DIR/borrow-unpin.rs:105:17
|
LL | let x = &pin mut foo; // ok
| ------------ first mutable borrow occurs here
Expand All @@ -82,7 +82,7 @@ LL | foo_pin_mut(x);
| - first borrow later used here

error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
--> $DIR/borrow-unpin.rs:100:17
--> $DIR/borrow-unpin.rs:116:17
|
LL | let x = &pin const foo; // ok
| -------------- immutable borrow occurs here
Expand All @@ -92,7 +92,7 @@ LL | foo_pin_ref(x);
| - immutable borrow later used here

error[E0502]: cannot borrow `foo` as immutable because it is also borrowed as mutable
--> $DIR/borrow-unpin.rs:111:17
--> $DIR/borrow-unpin.rs:127:17
|
LL | let x = &pin mut foo; // ok
| ------------ mutable borrow occurs here
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/pin-ergonomics/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,20 @@ fn baz(mut x: Foo, mut y: Foo) {
let _y = y; //~ ERROR cannot move out of `y` because it is pinned
}

fn ref_pin_mut_then_mut_borrow_and_move(mut x: Foo) {
{
let ref pin mut _x = x;
}
let _x = &mut x; //~ ERROR cannot borrow `x` as mutable because it is pinned
let _x = x; //~ ERROR cannot move out of `x` because it is pinned
}

fn ref_pin_const_then_mut_borrow_and_move(mut y: Foo) {
{
let ref pin const _y = y;
}
let _y = &mut y; //~ ERROR cannot borrow `y` as mutable because it is pinned
let _y = y; //~ ERROR cannot move out of `y` because it is pinned
}

fn main() {}
38 changes: 37 additions & 1 deletion tests/ui/pin-ergonomics/borrow.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,41 @@ LL | let _y = &pin const y;
LL | let _y = y;
| ^ move out of `y` occurs here

error: aborting due to 4 previous errors
error: cannot borrow `x` as mutable because it is pinned
--> $DIR/borrow.rs:51:14
|
LL | let ref pin mut _x = x;
| -------------- pin of `x` occurs here
LL | }
LL | let _x = &mut x;
| ^^^^^^ borrow of `x` as mutable occurs here

error: cannot move out of `x` because it is pinned
--> $DIR/borrow.rs:52:14
|
LL | let ref pin mut _x = x;
| -------------- pin of `x` occurs here
...
LL | let _x = x;
| ^ move out of `x` occurs here

error: cannot borrow `y` as mutable because it is pinned
--> $DIR/borrow.rs:59:14
|
LL | let ref pin const _y = y;
| ---------------- pin of `y` occurs here
LL | }
LL | let _y = &mut y;
| ^^^^^^ borrow of `y` as mutable occurs here

error: cannot move out of `y` because it is pinned
--> $DIR/borrow.rs:60:14
|
LL | let ref pin const _y = y;
| ---------------- pin of `y` occurs here
...
LL | let _y = y;
| ^ move out of `y` occurs here

error: aborting due to 8 previous errors

Loading