Remove most uses of allow(unions_with_drop_fields) in tests

This commit is contained in:
Simon Sapin 2019-07-03 12:35:02 +02:00 committed by Oliver Scherer
parent 0a08841bb0
commit 84ca0a1cb4
14 changed files with 118 additions and 121 deletions

View file

@ -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,

View file

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

View file

@ -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,
}

View file

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

View file

@ -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,

View file

@ -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`
}

View file

@ -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`.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,
}

View file

@ -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() {}