Remove most uses of allow(unions_with_drop_fields) in tests
This commit is contained in:
parent
0a08841bb0
commit
84ca0a1cb4
14 changed files with 118 additions and 121 deletions
|
|
@ -3,13 +3,13 @@
|
|||
#![feature(associated_type_bounds)]
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
#![allow(unions_with_drop_fields, unused_assignments)]
|
||||
#![allow(unused_assignments)]
|
||||
|
||||
trait Tr1 { type As1; }
|
||||
trait Tr2 { type As2; }
|
||||
trait Tr3 { type As3; }
|
||||
trait Tr4<'a> { type As4; }
|
||||
trait Tr5 { type As5; }
|
||||
trait Tr1: Copy { type As1: Copy; }
|
||||
trait Tr2: Copy { type As2: Copy; }
|
||||
trait Tr3: Copy { type As3: Copy; }
|
||||
trait Tr4<'a>: Copy { type As4: Copy; }
|
||||
trait Tr5: Copy { type As5: Copy; }
|
||||
|
||||
impl Tr1 for &str { type As1 = bool; }
|
||||
impl Tr2 for bool { type As2 = u8; }
|
||||
|
|
@ -71,7 +71,8 @@ where
|
|||
let _: &'a T = &x.f0;
|
||||
}
|
||||
|
||||
union UnSelf<T> where Self: Tr1<As1: Tr2> {
|
||||
#[derive(Copy, Clone)]
|
||||
union UnSelf<T> where Self: Tr1<As1: Tr2>, T: Copy {
|
||||
f0: T,
|
||||
f1: <Self as Tr1>::As1,
|
||||
f2: <<Self as Tr1>::As1 as Tr2>::As2,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(slice_patterns)]
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::Generator;
|
||||
use std::panic;
|
||||
use std::pin::Pin;
|
||||
|
|
@ -152,17 +153,16 @@ fn assignment1(a: &Allocator, c0: bool) {
|
|||
_v = _w;
|
||||
}
|
||||
|
||||
#[allow(unions_with_drop_fields)]
|
||||
union Boxy<T> {
|
||||
a: T,
|
||||
b: T,
|
||||
a: ManuallyDrop<T>,
|
||||
b: ManuallyDrop<T>,
|
||||
}
|
||||
|
||||
fn union1(a: &Allocator) {
|
||||
unsafe {
|
||||
let mut u = Boxy { a: a.alloc() };
|
||||
u.b = a.alloc();
|
||||
drop(u.a);
|
||||
let mut u = Boxy { a: ManuallyDrop::new(a.alloc()) };
|
||||
*u.b = a.alloc(); // drops first alloc
|
||||
drop(ManuallyDrop::into_inner(u.a));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
#![feature(rustc_attrs)]
|
||||
#![feature(untagged_unions)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
#[rustc_outlives]
|
||||
union Foo<'b, U> { //~ ERROR rustc_outlives
|
||||
union Foo<'b, U: Copy> { //~ ERROR rustc_outlives
|
||||
bar: Bar<'b, U>
|
||||
}
|
||||
|
||||
union Bar<'a, T> where T: 'a {
|
||||
union Bar<'a, T: Copy> where T: 'a {
|
||||
x: &'a (),
|
||||
y: T,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
#![feature(rustc_attrs)]
|
||||
#![feature(untagged_unions)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
#[rustc_outlives]
|
||||
union Foo<'a, T> { //~ ERROR rustc_outlives
|
||||
union Foo<'a, T: Copy> { //~ ERROR rustc_outlives
|
||||
field1: Bar<'a, T>
|
||||
}
|
||||
|
||||
// Type U needs to outlive lifetime 'b
|
||||
union Bar<'b, U> {
|
||||
union Bar<'b, U: Copy> {
|
||||
field2: &'b U
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
#![feature(untagged_unions)]
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
enum A<'a, T: 'a>
|
||||
where
|
||||
|
|
@ -24,6 +25,14 @@ where
|
|||
union C<'a, T: 'a>
|
||||
where
|
||||
Self: Send, T: PartialEq<Self>
|
||||
{
|
||||
foo: &'a Self,
|
||||
bar: ManuallyDrop<T>,
|
||||
}
|
||||
|
||||
union D<'a, T: 'a>
|
||||
where
|
||||
Self: Send, T: PartialEq<Self> + Copy
|
||||
{
|
||||
foo: &'a Self,
|
||||
bar: T,
|
||||
|
|
|
|||
|
|
@ -1,51 +1,90 @@
|
|||
#![feature(untagged_unions)]
|
||||
#![allow(unused)]
|
||||
|
||||
#[allow(unions_with_drop_fields)]
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[derive(Default)]
|
||||
struct MockBox<T> {
|
||||
value: [T; 1],
|
||||
}
|
||||
|
||||
impl<T> MockBox<T> {
|
||||
fn new(value: T) -> Self { MockBox { value: [value] } }
|
||||
}
|
||||
|
||||
impl<T> Deref for MockBox<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T { &self.value[0] }
|
||||
}
|
||||
|
||||
impl<T> DerefMut for MockBox<T> {
|
||||
fn deref_mut(&mut self) -> &mut T { &mut self.value[0] }
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MockVec<T> {
|
||||
value: [T; 0],
|
||||
}
|
||||
|
||||
impl<T> MockVec<T> {
|
||||
fn new() -> Self { MockVec { value: [] } }
|
||||
}
|
||||
|
||||
impl<T> Deref for MockVec<T> {
|
||||
type Target = [T];
|
||||
fn deref(&self) -> &[T] { &self.value }
|
||||
}
|
||||
|
||||
impl<T> DerefMut for MockVec<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] { &mut self.value }
|
||||
}
|
||||
|
||||
|
||||
union U {
|
||||
x: ((Vec<u8>, Vec<u8>), Vec<u8>),
|
||||
y: Box<Vec<u8>>,
|
||||
x: ((MockVec<u8>, MockVec<u8>), MockVec<u8>),
|
||||
y: MockBox<MockVec<u8>>,
|
||||
}
|
||||
|
||||
fn use_borrow<T>(_: &T) {}
|
||||
|
||||
unsafe fn parent_sibling_borrow() {
|
||||
let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
let mut u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
let a = &mut u.x.0;
|
||||
let b = &u.y; //~ ERROR cannot borrow `u` (via `u.y`)
|
||||
use_borrow(a);
|
||||
}
|
||||
|
||||
unsafe fn parent_sibling_move() {
|
||||
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
let a = u.x.0;
|
||||
let b = u.y; //~ ERROR use of moved value: `u`
|
||||
}
|
||||
|
||||
unsafe fn grandparent_sibling_borrow() {
|
||||
let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
let mut u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
let a = &mut (u.x.0).0;
|
||||
let b = &u.y; //~ ERROR cannot borrow `u` (via `u.y`)
|
||||
use_borrow(a);
|
||||
}
|
||||
|
||||
unsafe fn grandparent_sibling_move() {
|
||||
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
let a = (u.x.0).0;
|
||||
let b = u.y; //~ ERROR use of moved value: `u`
|
||||
}
|
||||
|
||||
unsafe fn deref_sibling_borrow() {
|
||||
let mut u = U { y: Box::default() };
|
||||
let mut u = U { y: MockBox::default() };
|
||||
let a = &mut *u.y;
|
||||
let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
|
||||
use_borrow(a);
|
||||
}
|
||||
|
||||
unsafe fn deref_sibling_move() {
|
||||
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
let a = *u.y;
|
||||
let b = u.x; //~ ERROR use of moved value: `u`
|
||||
let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
// No way to test deref-move without Box in union
|
||||
// let a = *u.y;
|
||||
// let b = u.x; ERROR use of moved value: `u`
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0`)
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:15:13
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:54:13
|
||||
|
|
||||
LL | let a = &mut u.x.0;
|
||||
| ---------- mutable borrow occurs here (via `u.x.0`)
|
||||
|
|
@ -11,9 +11,9 @@ LL | use_borrow(a);
|
|||
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0`
|
||||
|
||||
error[E0382]: use of moved value: `u`
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:22:13
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:61:13
|
||||
|
|
||||
LL | let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
LL | let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
| - move occurs because `u` has type `U`, which does not implement the `Copy` trait
|
||||
LL | let a = u.x.0;
|
||||
| ----- value moved here
|
||||
|
|
@ -21,7 +21,7 @@ LL | let b = u.y;
|
|||
| ^^^ value used here after move
|
||||
|
||||
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0.0`)
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:28:13
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:67:13
|
||||
|
|
||||
LL | let a = &mut (u.x.0).0;
|
||||
| -------------- mutable borrow occurs here (via `u.x.0.0`)
|
||||
|
|
@ -33,38 +33,28 @@ LL | use_borrow(a);
|
|||
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0.0`
|
||||
|
||||
error[E0382]: use of moved value: `u`
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:35:13
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:74:13
|
||||
|
|
||||
LL | let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
LL | let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
|
||||
| - move occurs because `u` has type `U`, which does not implement the `Copy` trait
|
||||
LL | let a = (u.x.0).0;
|
||||
| --------- value moved here
|
||||
LL | let b = u.y;
|
||||
| ^^^ value used here after move
|
||||
|
||||
error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `*u.y`)
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:41:13
|
||||
error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `u.y`)
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:80:13
|
||||
|
|
||||
LL | let a = &mut *u.y;
|
||||
| --------- mutable borrow occurs here (via `*u.y`)
|
||||
| --- mutable borrow occurs here (via `u.y`)
|
||||
LL | let b = &u.x;
|
||||
| ^^^^ immutable borrow of `u.x` -- which overlaps with `*u.y` -- occurs here
|
||||
| ^^^^ immutable borrow of `u.x` -- which overlaps with `u.y` -- occurs here
|
||||
LL | use_borrow(a);
|
||||
| - mutable borrow later used here
|
||||
|
|
||||
= note: `u.x` is a field of the union `U`, so it overlaps the field `*u.y`
|
||||
= note: `u.x` is a field of the union `U`, so it overlaps the field `u.y`
|
||||
|
||||
error[E0382]: use of moved value: `u`
|
||||
--> $DIR/union-borrow-move-parent-sibling.rs:48:13
|
||||
|
|
||||
LL | let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
|
||||
| - move occurs because `u` has type `U`, which does not implement the `Copy` trait
|
||||
LL | let a = *u.y;
|
||||
| ---- value moved here
|
||||
LL | let b = u.x;
|
||||
| ^^^ value used here after move
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0382, E0502.
|
||||
For more information about an error, try `rustc --explain E0382`.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
// Some traits can be derived for unions.
|
||||
|
||||
|
|
@ -24,11 +23,11 @@ impl PartialEq for U { fn eq(&self, rhs: &Self) -> bool { true } }
|
|||
Copy,
|
||||
Eq
|
||||
)]
|
||||
union W<T> {
|
||||
union W<T: Copy> {
|
||||
a: T,
|
||||
}
|
||||
|
||||
impl<T> PartialEq for W<T> { fn eq(&self, rhs: &Self) -> bool { true } }
|
||||
impl<T: Copy> PartialEq for W<T> { fn eq(&self, rhs: &Self) -> bool { true } }
|
||||
|
||||
fn main() {
|
||||
let u = U { b: 0 };
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
// run-pass
|
||||
#![allow(unused_assignments)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
// Drop works for union itself.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
struct S;
|
||||
|
||||
union U {
|
||||
a: S
|
||||
a: ManuallyDrop<S>
|
||||
}
|
||||
|
||||
impl Drop for S {
|
||||
|
|
@ -28,11 +29,11 @@ static mut CHECK: u8 = 0;
|
|||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let mut u = U { a: S };
|
||||
let mut u = U { a: ManuallyDrop::new(S) };
|
||||
assert_eq!(CHECK, 0);
|
||||
u = U { a: S };
|
||||
u = U { a: ManuallyDrop::new(S) };
|
||||
assert_eq!(CHECK, 1); // union itself is assigned, union is dropped, field is not dropped
|
||||
u.a = S;
|
||||
*u.a = S;
|
||||
assert_eq!(CHECK, 11); // union field is assigned, field is dropped
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
// Drop works for union itself.
|
||||
|
||||
|
|
@ -21,12 +20,6 @@ union Y {
|
|||
a: S,
|
||||
}
|
||||
|
||||
impl Drop for S {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CHECK += 10; }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for U {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CHECK += 1; }
|
||||
|
|
@ -51,10 +44,10 @@ fn main() {
|
|||
{
|
||||
let w = W { a: S };
|
||||
}
|
||||
assert_eq!(CHECK, 2); // 2, not 11, dtor of S is not called
|
||||
assert_eq!(CHECK, 2); // 2, dtor of W is called
|
||||
{
|
||||
let y = Y { a: S };
|
||||
}
|
||||
assert_eq!(CHECK, 2); // 2, not 12, dtor of S is not called
|
||||
assert_eq!(CHECK, 2); // 2, dtor of Y is called
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,24 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
union MaybeItem<T: Iterator> {
|
||||
union MaybeItem<T: Iterator> where T::Item: Copy {
|
||||
elem: T::Item,
|
||||
none: (),
|
||||
}
|
||||
|
||||
union U<A, B> {
|
||||
union U<A, B> where A: Copy, B: Copy {
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
||||
unsafe fn union_transmute<A, B>(a: A) -> B {
|
||||
unsafe fn union_transmute<A, B>(a: A) -> B where A: Copy, B: Copy {
|
||||
U { a: a }.b
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let u = U::<String, Vec<u8>> { a: String::from("abcd") };
|
||||
|
||||
assert_eq!(u.b.len(), 4);
|
||||
assert_eq!(u.b[0], b'a');
|
||||
|
||||
let b = union_transmute::<(u8, u8), u16>((1, 1));
|
||||
assert_eq!(b, (1 << 8) + 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
#![allow(unions_with_drop_fields)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::intrinsics::needs_drop;
|
||||
use std::mem::needs_drop;
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
struct NeedDrop;
|
||||
|
||||
|
|
@ -16,10 +15,10 @@ impl Drop for NeedDrop {
|
|||
|
||||
// Constant expressios allow `NoDrop` to go out of scope,
|
||||
// unlike a value of the interior type implementing `Drop`.
|
||||
static X: () = (NoDrop { inner: NeedDrop }, ()).1;
|
||||
static X: () = (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1;
|
||||
|
||||
// A union that scrubs the drop glue from its inner type
|
||||
union NoDrop<T> {inner: T}
|
||||
union NoDrop<T> { inner: ManuallyDrop<T> }
|
||||
|
||||
// Copy currently can't be implemented on drop-containing unions,
|
||||
// this may change later
|
||||
|
|
@ -40,7 +39,7 @@ struct Baz {
|
|||
y: Box<u8>,
|
||||
}
|
||||
|
||||
union ActuallyDrop<T> {inner: T}
|
||||
union ActuallyDrop<T> { inner: ManuallyDrop<T> }
|
||||
|
||||
impl<T> Drop for ActuallyDrop<T> {
|
||||
fn drop(&mut self) {}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
// run-pass
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct Pair<T, U>(T, U);
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct Triple<T>(T, T, T);
|
||||
|
||||
#[repr(C)]
|
||||
union U<A, B> {
|
||||
union U<A, B>
|
||||
where
|
||||
A: Copy, B: Copy
|
||||
{
|
||||
a: Pair<A, A>,
|
||||
b: B,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
union W<A, B> {
|
||||
union W<A, B>
|
||||
where
|
||||
A: Copy, B: Copy
|
||||
{
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
union U {
|
||||
a: u8, // OK
|
||||
}
|
||||
|
||||
union W {
|
||||
a: String, // OK
|
||||
b: String, // OK
|
||||
}
|
||||
|
||||
struct S(String);
|
||||
|
||||
// `S` doesn't implement `Drop` trait, but still has non-trivial destructor
|
||||
union Y {
|
||||
a: S, // OK
|
||||
}
|
||||
|
||||
// We don't know if `T` is trivially-destructable or not until trans
|
||||
union J<T> {
|
||||
a: T, // OK
|
||||
}
|
||||
|
||||
union H<T: Copy> {
|
||||
a: T, // OK
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue