rust/tests/ui/pin-ergonomics/borrow-unpin.rs

144 lines
4.1 KiB
Rust

//@ revisions: unpin pinned
#![feature(pin_ergonomics)]
#![allow(dead_code, incomplete_features)]
// For now, in order to ensure soundness, we move the place in `&pin mut place`
// if `place` is not `Unpin`.
// In the next step, we borrow the place instead of moving it, after that we
// have to makes sure `&pin mut place` and `&pin const place` cannot violate
// the mut-xor-share rules.
use std::pin::Pin;
use std::marker::PhantomPinned;
#[cfg(pinned)]
#[derive(Default)]
struct Foo(PhantomPinned);
#[cfg(unpin)]
#[derive(Default)]
struct Foo;
fn foo_mut(_: &mut Foo) {
}
fn foo_ref(_: &Foo) {
}
fn foo_pin_mut(_: Pin<&mut Foo>) {
}
fn foo_pin_ref(_: Pin<&Foo>) {
}
fn foo_move(_: Foo) {}
fn immutable_pin_mut_then_move() {
let foo = Foo::default();
foo_pin_mut(&pin mut foo); //[unpin]~ ERROR cannot borrow `foo` as mutable, as it is not declared as mutable
foo_move(foo); //[pinned]~ ERROR use of moved value: `foo`
let foo = Foo::default();
let x = &pin mut foo; //[unpin]~ ERROR cannot borrow `foo` as mutable, as it is not declared as mutable
foo_move(foo); //[pinned]~ ERROR use of moved value: `foo`
//[unpin]~^ ERROR cannot move out of `foo` because it is borrowed
foo_pin_mut(x); //
}
fn pin_mut_then_move() {
let mut foo = Foo::default();
foo_pin_mut(&pin mut foo); // ok
foo_move(foo); //[pinned]~ ERROR use of moved value: `foo`
let mut foo = Foo::default();
let x = &pin mut foo; // ok
foo_move(foo); //[pinned]~ ERROR use of moved value: `foo`
//[unpin]~^ ERROR cannot move out of `foo` because it is borrowed
foo_pin_mut(x); //
}
fn pin_ref_then_move() {
let foo = Foo::default();
foo_pin_ref(&pin const foo); // ok
foo_move(foo); // ok
let foo = Foo::default();
let x = &pin const foo; // ok
foo_move(foo); //[pinned]~ ERROR cannot move out of `foo` because it is borrowed
//[unpin]~^ ERROR cannot move out of `foo` because it is borrowed
foo_pin_ref(x);
}
fn pin_mut_then_ref() {
let mut foo = Foo::default();
foo_pin_mut(&pin mut foo); // ok
foo_ref(&foo); //[pinned]~ ERROR borrow of moved value: `foo`
let mut foo = Foo::default();
let x = &pin mut foo; // ok
foo_ref(&foo); //[pinned]~ ERROR borrow of moved value: `foo`
//[unpin]~^ ERROR cannot borrow `foo` as immutable because it is also borrowed as mutable
foo_pin_mut(x);
}
fn pin_ref_then_ref() {
let mut foo = Foo::default();
foo_pin_ref(&pin const foo); // ok
foo_ref(&foo); // ok
let mut foo = Foo::default();
let x = &pin const foo; // ok
foo_ref(&foo); // ok
foo_pin_ref(x);
}
fn pin_mut_then_pin_mut() {
let mut foo = Foo::default();
foo_pin_mut(&pin mut foo); // ok
foo_pin_mut(&pin mut foo); //[pinned]~ ERROR use of moved value: `foo`
let mut foo = Foo::default();
let x = &pin mut foo; // ok
foo_pin_mut(&pin mut foo); //[pinned]~ ERROR use of moved value: `foo`
//[unpin]~^ ERROR cannot borrow `foo` as mutable more than once at a time
foo_pin_mut(x);
}
fn pin_ref_then_pin_mut() {
let mut foo = Foo::default();
foo_pin_ref(&pin const foo); // ok
foo_pin_mut(&pin mut foo); // ok
let mut foo = Foo::default();
let x = &pin const foo; // ok
foo_pin_mut(&pin mut foo); //[pinned]~ ERROR cannot move out of `foo` because it is borrowed
//[unpin]~^ ERROR cannot borrow `foo` as mutable because it is also borrowed as immutable
foo_pin_ref(x);
}
fn pin_mut_then_pin_ref() {
let mut foo = Foo::default();
foo_pin_mut(&pin mut foo); // ok
foo_pin_ref(&pin const foo); //[pinned]~ ERROR borrow of moved value: `foo`
let mut foo = Foo::default();
let x = &pin mut foo; // ok
foo_pin_ref(&pin const foo); //[pinned]~ ERROR borrow of moved value: `foo`
//[unpin]~^ ERROR cannot borrow `foo` as immutable because it is also borrowed as mutable
foo_pin_mut(x);
}
fn pin_ref_then_pin_ref() {
let mut foo = Foo::default();
foo_pin_ref(&pin const foo); // ok
foo_pin_ref(&pin const foo); // ok
let mut foo = Foo::default();
let x = &pin const foo; // ok
foo_pin_ref(&pin const foo); // ok
foo_pin_ref(x);
}
fn main() {}