remove untagged_union feature gate

This commit is contained in:
Ralf Jung 2022-06-29 22:33:18 -04:00
parent 6dfede3b9d
commit 5bf6017b87
57 changed files with 386 additions and 449 deletions

View file

@ -525,13 +525,6 @@ declare_features! (
(incomplete, unsized_locals, "1.30.0", Some(48055), None),
/// Allows unsized tuple coercion.
(active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
/// Allows `union`s to implement `Drop`. Moreover, `union`s may now include fields
/// that don't implement `Copy` as long as they don't have any drop glue.
/// This is checked recursively. On encountering type variable where no progress can be made,
/// `T: Copy` is used as a substitute for "no drop glue".
///
/// NOTE: A limited form of `union U { ... }` was accepted in 1.19.0.
(active, untagged_unions, "1.13.0", Some(55149), None),
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
(active, used_with_arg, "1.60.0", Some(93798), None),
/// Allows `extern "wasm" fn`

View file

@ -180,6 +180,9 @@ declare_features! (
/// Allows using items which are missing stability attributes
(removed, unmarked_api, "1.0.0", None, None, None),
(removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
/// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
(removed, untagged_unions, "1.13.0", Some(55149), None,
Some("unions with `Copy` and `MaybeUninit` fields are stable; there is no intent to stabilize more")),
/// Allows `#[unwind(..)]`.
///
/// Permits specifying whether a function should permit unwinding or abort on unwind.

View file

@ -13,13 +13,12 @@ use rustc_hir::{FieldDef, Generics, HirId, Item, ItemKind, TraitRef, Ty, TyKind,
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
use rustc_middle::ty::{self, query::Providers, TyCtxt};
use rustc_middle::ty::{query::Providers, TyCtxt};
use rustc_session::lint;
use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
use std::cmp::Ordering;
@ -766,69 +765,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
}
}
// There's no good place to insert stability check for non-Copy unions,
// so semi-randomly perform it here in stability.rs
hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
let ty = self.tcx.type_of(item.def_id);
let ty::Adt(adt_def, substs) = ty.kind() else { bug!() };
#[allow(rustc::usage_of_qualified_ty)] // `Ty` is `hir::Ty` here, we really want `ty::Ty`.
fn allowed_union_field<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: ty::Ty<'tcx>,
) -> bool {
// We don't just accept all !needs_drop fields, due to semver concerns.
match ty.kind() {
ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check)
ty::Tuple(tys) => {
// allow tuples of allowed types
tys.iter().all(|ty| allowed_union_field(tcx, param_env, ty))
}
ty::Array(elem, _len) => {
// Like `Copy`, we do *not* special-case length 0.
allowed_union_field(tcx, param_env, *elem)
}
_ => {
// Fallback case: allow `ManuallyDrop` and things that are `Copy`.
ty.ty_adt_def().map_or(false, |adt_def| adt_def.is_manually_drop())
|| ty.is_copy_modulo_regions(tcx.at(DUMMY_SP), param_env)
}
}
}
// `allowed_union_field` determines which fields are allowed on stable.
let param_env = self.tcx.param_env(item.def_id);
for field in &adt_def.non_enum_variant().fields {
let field_ty = field.ty(self.tcx, substs);
if !allowed_union_field(self.tcx, param_env, field_ty) {
if field_ty.needs_drop(self.tcx, param_env) {
// Avoid duplicate error: This will error later anyway because fields
// that need drop are not allowed.
self.tcx.sess.delay_span_bug(
item.span,
"union should have been rejected due to potentially dropping field",
);
} else {
feature_err(
&self.tcx.sess.parse_sess,
sym::untagged_unions,
self.tcx.def_span(field.did),
"unions with non-`Copy` fields other than `ManuallyDrop<T>`, \
references, and tuples of such types are unstable",
)
.emit();
}
} else {
// We allow this field. Make extra sure it does not drop.
assert!(
!field_ty.needs_drop(self.tcx, param_env),
"we should accept no maybe-dropping union fields"
);
}
}
}
_ => (/* pass */),
}
intravisit::walk_item(self, item);

View file

@ -402,11 +402,37 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
let item_type = tcx.type_of(item_def_id);
if let ty::Adt(def, substs) = item_type.kind() {
assert!(def.is_union());
let fields = &def.non_enum_variant().fields;
fn allowed_union_field<'tcx>(
ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
span: Span,
) -> bool {
// We don't just accept all !needs_drop fields, due to semver concerns.
match ty.kind() {
ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check)
ty::Tuple(tys) => {
// allow tuples of allowed types
tys.iter().all(|ty| allowed_union_field(ty, tcx, param_env, span))
}
ty::Array(elem, _len) => {
// Like `Copy`, we do *not* special-case length 0.
allowed_union_field(*elem, tcx, param_env, span)
}
_ => {
// Fallback case: allow `ManuallyDrop` and things that are `Copy`.
ty.ty_adt_def().map_or(false, |adt_def| adt_def.is_manually_drop())
|| ty.is_copy_modulo_regions(tcx.at(span), param_env)
}
}
}
let param_env = tcx.param_env(item_def_id);
for field in fields {
for field in &def.non_enum_variant().fields {
let field_ty = field.ty(tcx, substs);
if field_ty.needs_drop(tcx, param_env) {
if !allowed_union_field(field_ty, tcx, param_env, span) {
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
// We are currently checking the type this field came from, so it must be local.
Some(Node::Field(field)) => (field.span, field.ty.span),
@ -433,6 +459,9 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
)
.emit();
return false;
} else if field_ty.needs_drop(tcx, param_env) {
// This should never happen. But we can get here e.g. in case of name resolution errors.
tcx.sess.delay_span_bug(span, "we should never accept maybe-dropping union fields");
}
}
} else {

View file

@ -1,8 +1,8 @@
#![feature(associated_type_bounds)]
#![feature(type_alias_impl_trait)]
#![feature(untagged_unions)]
use std::iter;
use std::mem::ManuallyDrop;
struct SI1<T: Iterator<Item: Copy, Item: Send>> {
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
@ -74,36 +74,36 @@ where
union UI1<T: Iterator<Item: Copy, Item: Send>> {
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
f: T,
f: ManuallyDrop<T>,
}
union UI2<T: Iterator<Item: Copy, Item: Copy>> {
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
f: T,
f: ManuallyDrop<T>,
}
union UI3<T: Iterator<Item: 'static, Item: 'static>> {
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
f: T,
f: ManuallyDrop<T>,
}
union UW1<T>
where
T: Iterator<Item: Copy, Item: Send>,
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
{
f: T,
f: ManuallyDrop<T>,
}
union UW2<T>
where
T: Iterator<Item: Copy, Item: Copy>,
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
{
f: T,
f: ManuallyDrop<T>,
}
union UW3<T>
where
T: Iterator<Item: 'static, Item: 'static>,
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
{
f: T,
f: ManuallyDrop<T>,
}
fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}

View file

@ -1,5 +1,6 @@
#![feature(associated_type_bounds)]
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
struct S1 { f: dyn Iterator<Item: Copy> }
//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
@ -17,12 +18,12 @@ enum E3 { V(dyn Iterator<Item: 'static>) }
//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized> + 'static)`
union U1 { f: dyn Iterator<Item: Copy> }
union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)`
union U2 { f: Box<dyn Iterator<Item: Copy>> }
union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
union U3 { f: dyn Iterator<Item: 'static> }
union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
//~^ ERROR associated type bounds are not allowed within structs, enums, or unions
//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized> + 'static)`

View file

@ -1,59 +1,59 @@
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:4:29
--> $DIR/inside-adt.rs:5:29
|
LL | struct S1 { f: dyn Iterator<Item: Copy> }
| ^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:6:33
--> $DIR/inside-adt.rs:7:33
|
LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
| ^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:8:29
--> $DIR/inside-adt.rs:9:29
|
LL | struct S3 { f: dyn Iterator<Item: 'static> }
| ^^^^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:11:26
--> $DIR/inside-adt.rs:12:26
|
LL | enum E1 { V(dyn Iterator<Item: Copy>) }
| ^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:14:30
--> $DIR/inside-adt.rs:15:30
|
LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
| ^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:16:26
--> $DIR/inside-adt.rs:17:26
|
LL | enum E3 { V(dyn Iterator<Item: 'static>) }
| ^^^^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:20:28
--> $DIR/inside-adt.rs:21:41
|
LL | union U1 { f: dyn Iterator<Item: Copy> }
| ^^^^^^^^^^
LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
| ^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:23:32
--> $DIR/inside-adt.rs:24:45
|
LL | union U2 { f: Box<dyn Iterator<Item: Copy>> }
| ^^^^^^^^^^
LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
| ^^^^^^^^^^
error: associated type bounds are not allowed within structs, enums, or unions
--> $DIR/inside-adt.rs:25:28
--> $DIR/inside-adt.rs:26:41
|
LL | union U3 { f: dyn Iterator<Item: 'static> }
| ^^^^^^^^^^^^^
LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
| ^^^^^^^^^^^^^
error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time
--> $DIR/inside-adt.rs:11:13
--> $DIR/inside-adt.rs:12:13
|
LL | enum E1 { V(dyn Iterator<Item: Copy>) }
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -71,7 +71,7 @@ LL | enum E1 { V(Box<dyn Iterator<Item: Copy>>) }
| ++++ +
error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized> + 'static)` cannot be known at compilation time
--> $DIR/inside-adt.rs:16:13
--> $DIR/inside-adt.rs:17:13
|
LL | enum E3 { V(dyn Iterator<Item: 'static>) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -89,40 +89,42 @@ LL | enum E3 { V(Box<dyn Iterator<Item: 'static>>) }
| ++++ +
error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time
--> $DIR/inside-adt.rs:20:15
--> $DIR/inside-adt.rs:21:15
|
LL | union U1 { f: dyn Iterator<Item: Copy> }
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)`
= help: within `ManuallyDrop<(dyn Iterator<Item = impl Copy> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)`
= note: required because it appears within the type `ManuallyDrop<(dyn Iterator<Item = impl Copy> + 'static)>`
= note: no field of a union may have a dynamically sized type
= help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
|
LL | union U1 { f: &dyn Iterator<Item: Copy> }
LL | union U1 { f: &ManuallyDrop<dyn Iterator<Item: Copy>> }
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
LL | union U1 { f: Box<dyn Iterator<Item: Copy>> }
| ++++ +
LL | union U1 { f: Box<ManuallyDrop<dyn Iterator<Item: Copy>>> }
| ++++ +
error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized> + 'static)` cannot be known at compilation time
--> $DIR/inside-adt.rs:25:15
--> $DIR/inside-adt.rs:26:15
|
LL | union U3 { f: dyn Iterator<Item: 'static> }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized> + 'static)`
= help: within `ManuallyDrop<(dyn Iterator<Item = impl Sized> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized> + 'static)`
= note: required because it appears within the type `ManuallyDrop<(dyn Iterator<Item = impl Sized> + 'static)>`
= note: no field of a union may have a dynamically sized type
= help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
|
LL | union U3 { f: &dyn Iterator<Item: 'static> }
LL | union U3 { f: &ManuallyDrop<dyn Iterator<Item: 'static>> }
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
LL | union U3 { f: Box<dyn Iterator<Item: 'static>> }
| ++++ +
LL | union U3 { f: Box<ManuallyDrop<dyn Iterator<Item: 'static>>> }
| ++++ +
error: aborting due to 13 previous errors

View file

@ -1,7 +1,6 @@
// run-pass
#![feature(associated_type_bounds)]
#![feature(untagged_unions)]
#![allow(unused_assignments)]

View file

@ -3,9 +3,9 @@
// captures the behavior of how `_` bindings are handled with respect to how we
// flag expressions that are meant to request unsafe blocks.
#![feature(untagged_unions)]
#[derive(Copy, Clone)]
struct I(i64);
#[derive(Copy, Clone)]
struct F(f64);
union U { a: I, b: F }

View file

@ -1,31 +1,31 @@
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
// Non-copy
struct A;
struct B;
union U {
a: A,
b: B,
a: ManuallyDrop<A>,
b: ManuallyDrop<B>,
}
fn main() {
unsafe {
{
let mut u = U { a: A };
let mut u = U { a: ManuallyDrop::new(A) };
let a = u.a;
let a = u.a; //~ ERROR use of moved value: `u`
}
{
let mut u = U { a: A };
let mut u = U { a: ManuallyDrop::new(A) };
let a = u.a;
u.a = A;
u.a = ManuallyDrop::new(A);
let a = u.a; // OK
}
{
let mut u = U { a: A };
let mut u = U { a: ManuallyDrop::new(A) };
let a = u.a;
u.b = B;
u.b = ManuallyDrop::new(B);
let a = u.a; // OK
}
}

View file

@ -1,7 +1,7 @@
error[E0382]: use of moved value: `u`
--> $DIR/borrowck-union-move-assign.rs:17:21
|
LL | let mut u = U { a: A };
LL | let mut u = U { a: ManuallyDrop::new(A) };
| ----- move occurs because `u` has type `U`, which does not implement the `Copy` trait
LL | let a = u.a;
| --- value moved here

View file

@ -1,12 +1,12 @@
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
#[derive(Clone, Copy)]
struct Copy;
struct NonCopy;
union Unn {
n1: NonCopy,
n2: NonCopy,
n1: ManuallyDrop<NonCopy>,
n2: ManuallyDrop<NonCopy>,
}
union Ucc {
c1: Copy,
@ -14,24 +14,24 @@ union Ucc {
}
union Ucn {
c: Copy,
n: NonCopy,
n: ManuallyDrop<NonCopy>,
}
fn main() {
unsafe {
// 2 NonCopy
{
let mut u = Unn { n1: NonCopy };
let mut u = Unn { n1: ManuallyDrop::new(NonCopy) };
let a = u.n1;
let a = u.n1; //~ ERROR use of moved value: `u`
}
{
let mut u = Unn { n1: NonCopy };
let mut u = Unn { n1: ManuallyDrop::new(NonCopy) };
let a = u.n1;
let a = u; //~ ERROR use of moved value: `u`
}
{
let mut u = Unn { n1: NonCopy };
let mut u = Unn { n1: ManuallyDrop::new(NonCopy) };
let a = u.n1;
let a = u.n2; //~ ERROR use of moved value: `u`
}

View file

@ -1,7 +1,7 @@
error[E0382]: use of moved value: `u`
--> $DIR/borrowck-union-move.rs:26:21
|
LL | let mut u = Unn { n1: NonCopy };
LL | let mut u = Unn { n1: ManuallyDrop::new(NonCopy) };
| ----- move occurs because `u` has type `Unn`, which does not implement the `Copy` trait
LL | let a = u.n1;
| ---- value moved here
@ -11,7 +11,7 @@ LL | let a = u.n1;
error[E0382]: use of moved value: `u`
--> $DIR/borrowck-union-move.rs:31:21
|
LL | let mut u = Unn { n1: NonCopy };
LL | let mut u = Unn { n1: ManuallyDrop::new(NonCopy) };
| ----- move occurs because `u` has type `Unn`, which does not implement the `Copy` trait
LL | let a = u.n1;
| ---- value moved here
@ -21,7 +21,7 @@ LL | let a = u;
error[E0382]: use of moved value: `u`
--> $DIR/borrowck-union-move.rs:36:21
|
LL | let mut u = Unn { n1: NonCopy };
LL | let mut u = Unn { n1: ManuallyDrop::new(NonCopy) };
| ----- move occurs because `u` has type `Unn`, which does not implement the `Copy` trait
LL | let a = u.n1;
| ---- value moved here

View file

@ -1,8 +1,6 @@
// Moving from a reference/raw pointer should be an error, even when they're
// the field of a union.
#![feature(untagged_unions)]
union Pointers {
a: &'static String,
b: &'static mut String,

View file

@ -1,23 +1,23 @@
error[E0507]: cannot move out of `*u.a` which is behind a shared reference
--> $DIR/move-from-union-field-issue-66500.rs:14:5
--> $DIR/move-from-union-field-issue-66500.rs:12:5
|
LL | *u.a
| ^^^^ move occurs because `*u.a` has type `String`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `*u.b` which is behind a mutable reference
--> $DIR/move-from-union-field-issue-66500.rs:18:5
--> $DIR/move-from-union-field-issue-66500.rs:16:5
|
LL | *u.b
| ^^^^ move occurs because `*u.b` has type `String`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `*u.c` which is behind a raw pointer
--> $DIR/move-from-union-field-issue-66500.rs:22:5
--> $DIR/move-from-union-field-issue-66500.rs:20:5
|
LL | *u.c
| ^^^^ move occurs because `*u.c` has type `String`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `*u.d` which is behind a raw pointer
--> $DIR/move-from-union-field-issue-66500.rs:26:5
--> $DIR/move-from-union-field-issue-66500.rs:24:5
|
LL | *u.d
| ^^^^ move occurs because `*u.d` has type `String`, which does not implement the `Copy` trait

View file

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/invalid-union.rs:40:1
--> $DIR/invalid-union.rs:41:1
|
LL | fn main() {
| ^^^^^^^^^ constructing invalid value at .<deref>.y.<enum-variant(B)>.0: encountered `UnsafeCell` in a `const`
@ -10,7 +10,7 @@ LL | fn main() {
}
error: erroneous constant used
--> $DIR/invalid-union.rs:41:25
--> $DIR/invalid-union.rs:42:25
|
LL | let _: &'static _ = &C;
| ^^ referenced constant has errors
@ -24,7 +24,7 @@ error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
Future incompatibility report: Future breakage diagnostic:
error: erroneous constant used
--> $DIR/invalid-union.rs:41:25
--> $DIR/invalid-union.rs:42:25
|
LL | let _: &'static _ = &C;
| ^^ referenced constant has errors

View file

@ -9,8 +9,9 @@
// build-fail
// stderr-per-bitwidth
#![feature(const_mut_refs)]
#![feature(untagged_unions)]
use std::cell::Cell;
use std::mem::ManuallyDrop;
#[repr(C)]
struct S {
@ -25,7 +26,7 @@ enum E {
}
union U {
cell: Cell<u32>,
cell: ManuallyDrop<Cell<u32>>,
}
const C: S = {

View file

@ -1,18 +1,19 @@
// Checks that unions use type based qualification. Regression test for issue #90268.
#![feature(untagged_unions)]
use std::cell::Cell;
use std::mem::ManuallyDrop;
union U { i: u32, c: Cell<u32> }
union U { i: u32, c: ManuallyDrop<Cell<u32>> }
const C1: Cell<u32> = {
unsafe { U { c: Cell::new(0) }.c }
const C1: ManuallyDrop<Cell<u32>> = {
unsafe { U { c: ManuallyDrop::new(Cell::new(0)) }.c }
};
const C2: Cell<u32> = {
const C2: ManuallyDrop<Cell<u32>> = {
unsafe { U { i : 0 }.c }
};
const C3: Cell<u32> = {
const C3: ManuallyDrop<Cell<u32>> = {
let mut u = U { i: 0 };
u.i = 1;
unsafe { u.c }

View file

@ -1,5 +1,5 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:27:26
--> $DIR/qualif-union.rs:28:26
|
LL | let _: &'static _ = &C1;
| ---------- ^^ creates a temporary which is freed while still in use
@ -10,7 +10,7 @@ LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:28:26
--> $DIR/qualif-union.rs:29:26
|
LL | let _: &'static _ = &C2;
| ---------- ^^ creates a temporary which is freed while still in use
@ -21,7 +21,7 @@ LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:29:26
--> $DIR/qualif-union.rs:30:26
|
LL | let _: &'static _ = &C3;
| ---------- ^^ creates a temporary which is freed while still in use
@ -32,7 +32,7 @@ LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:30:26
--> $DIR/qualif-union.rs:31:26
|
LL | let _: &'static _ = &C4;
| ---------- ^^ creates a temporary which is freed while still in use
@ -43,7 +43,7 @@ LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:31:26
--> $DIR/qualif-union.rs:32:26
|
LL | let _: &'static _ = &C5;
| ---------- ^^ creates a temporary which is freed while still in use

View file

@ -1,7 +1,7 @@
// compile-flags: -Zsave-analysis
// This is also a regression test for #69415 and the above flag is needed.
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
trait Tr1 { type As1: Copy; }
trait Tr2 { type As2: Copy; }
@ -36,9 +36,9 @@ enum _En1<T: Tr1<As1: Tr2>> {
union _Un1<T: Tr1<As1: Tr2>> {
//~^ ERROR associated type bounds are unstable
outest: std::mem::ManuallyDrop<T>,
outer: T::As1,
inner: <T::As1 as Tr2>::As2,
outest: ManuallyDrop<T>,
outer: ManuallyDrop<T::As1>,
inner: ManuallyDrop<<T::As1 as Tr2>::As2>,
}
type _TaWhere1<T> where T: Iterator<Item: Copy> = T;

View file

@ -1,27 +1,27 @@
// check-pass
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
struct A;
struct B;
union U {
a: A,
b: B,
a: ManuallyDrop<A>,
b: ManuallyDrop<B>,
}
fn main() {
unsafe {
{
let mut u = U { a: A };
let mut u = U { a: ManuallyDrop::new(A) };
let a = u.a;
u.a = A;
u.a = ManuallyDrop::new(A);
let a = u.a; // OK
}
{
let mut u = U { a: A };
let mut u = U { a: ManuallyDrop::new(A) };
let a = u.a;
u.b = B;
u.b = ManuallyDrop::new(B);
let a = u.a; // OK
}
}

View file

@ -1,16 +1,19 @@
#![feature(untagged_unions)]
#![allow(dead_code)]
#[repr(align(16))]
#[derive(Clone, Copy)]
struct SA(i32);
#[derive(Clone, Copy)]
struct SB(SA);
#[repr(align(16))]
#[derive(Clone, Copy)]
union UA {
i: i32
}
#[derive(Clone, Copy)]
union UB {
a: UA
}

View file

@ -1,5 +1,5 @@
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:19:1
--> $DIR/repr-packed-contains-align.rs:22:1
|
LL | struct SC(SA);
| ^^^^^^^^^
@ -11,7 +11,7 @@ LL | struct SA(i32);
| ^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:22:1
--> $DIR/repr-packed-contains-align.rs:25:1
|
LL | struct SD(SB);
| ^^^^^^^^^
@ -22,86 +22,86 @@ note: `SA` has a `#[repr(align)]` attribute
LL | struct SA(i32);
| ^^^^^^^^^
note: `SD` contains a field of type `SB`
--> $DIR/repr-packed-contains-align.rs:22:11
--> $DIR/repr-packed-contains-align.rs:25:11
|
LL | struct SD(SB);
| ^^
note: ...which contains a field of type `SA`
--> $DIR/repr-packed-contains-align.rs:7:11
--> $DIR/repr-packed-contains-align.rs:8:11
|
LL | struct SB(SA);
| ^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:25:1
--> $DIR/repr-packed-contains-align.rs:28:1
|
LL | struct SE(UA);
| ^^^^^^^^^
|
note: `UA` has a `#[repr(align)]` attribute
--> $DIR/repr-packed-contains-align.rs:10:1
--> $DIR/repr-packed-contains-align.rs:12:1
|
LL | union UA {
| ^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:28:1
--> $DIR/repr-packed-contains-align.rs:31:1
|
LL | struct SF(UB);
| ^^^^^^^^^
|
note: `UA` has a `#[repr(align)]` attribute
--> $DIR/repr-packed-contains-align.rs:10:1
--> $DIR/repr-packed-contains-align.rs:12:1
|
LL | union UA {
| ^^^^^^^^
note: `SF` contains a field of type `UB`
--> $DIR/repr-packed-contains-align.rs:28:11
--> $DIR/repr-packed-contains-align.rs:31:11
|
LL | struct SF(UB);
| ^^
note: ...which contains a field of type `UA`
--> $DIR/repr-packed-contains-align.rs:15:5
--> $DIR/repr-packed-contains-align.rs:18:5
|
LL | a: UA
| ^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:31:1
--> $DIR/repr-packed-contains-align.rs:34:1
|
LL | union UC {
| ^^^^^^^^
|
note: `UA` has a `#[repr(align)]` attribute
--> $DIR/repr-packed-contains-align.rs:10:1
--> $DIR/repr-packed-contains-align.rs:12:1
|
LL | union UA {
| ^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:36:1
--> $DIR/repr-packed-contains-align.rs:39:1
|
LL | union UD {
| ^^^^^^^^
|
note: `UA` has a `#[repr(align)]` attribute
--> $DIR/repr-packed-contains-align.rs:10:1
--> $DIR/repr-packed-contains-align.rs:12:1
|
LL | union UA {
| ^^^^^^^^
note: `UD` contains a field of type `UB`
--> $DIR/repr-packed-contains-align.rs:37:5
--> $DIR/repr-packed-contains-align.rs:40:5
|
LL | n: UB
| ^
note: ...which contains a field of type `UA`
--> $DIR/repr-packed-contains-align.rs:15:5
--> $DIR/repr-packed-contains-align.rs:18:5
|
LL | a: UA
| ^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:41:1
--> $DIR/repr-packed-contains-align.rs:44:1
|
LL | union UE {
| ^^^^^^^^
@ -113,7 +113,7 @@ LL | struct SA(i32);
| ^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> $DIR/repr-packed-contains-align.rs:46:1
--> $DIR/repr-packed-contains-align.rs:49:1
|
LL | union UF {
| ^^^^^^^^
@ -124,12 +124,12 @@ note: `SA` has a `#[repr(align)]` attribute
LL | struct SA(i32);
| ^^^^^^^^^
note: `UF` contains a field of type `SB`
--> $DIR/repr-packed-contains-align.rs:47:5
--> $DIR/repr-packed-contains-align.rs:50:5
|
LL | n: SB
| ^
note: ...which contains a field of type `SA`
--> $DIR/repr-packed-contains-align.rs:7:11
--> $DIR/repr-packed-contains-align.rs:8:11
|
LL | struct SB(SA);
| ^^

View file

@ -1,11 +1,11 @@
#![feature(rustc_attrs)]
#![feature(untagged_unions)]
#[rustc_outlives]
union Foo<'b, U: Copy> { //~ ERROR rustc_outlives
bar: Bar<'b, U>
}
#[derive(Clone, Copy)]
union Bar<'a, T: Copy> where T: 'a {
x: &'a (),
y: T,

View file

@ -1,5 +1,5 @@
error: rustc_outlives
--> $DIR/explicit-union.rs:5:1
--> $DIR/explicit-union.rs:4:1
|
LL | union Foo<'b, U: Copy> {
| ^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,5 +1,4 @@
#![feature(rustc_attrs)]
#![feature(untagged_unions)]
#[rustc_outlives]
union Foo<'a, T: Copy> { //~ ERROR rustc_outlives
@ -7,6 +6,7 @@ union Foo<'a, T: Copy> { //~ ERROR rustc_outlives
}
// Type U needs to outlive lifetime 'b
#[derive(Clone, Copy)]
union Bar<'b, U: Copy> {
field2: &'b U
}

View file

@ -1,5 +1,5 @@
error: rustc_outlives
--> $DIR/nested-union.rs:5:1
--> $DIR/nested-union.rs:4:1
|
LL | union Foo<'a, T: Copy> {
| ^^^^^^^^^^^^^^^^^^^^^^

View file

@ -25,8 +25,8 @@ union U3 {
a: String, //~ ERROR unions cannot contain fields that may need dropping
}
union U32 { // field that does not drop but is not `Copy`, either -- this is the real feature gate test!
a: std::cell::RefCell<i32>, //~ ERROR unions with non-`Copy` fields other than `ManuallyDrop<T>`, references, and tuples of such types are unstable
union U32 { // field that does not drop but is not `Copy`, either
a: std::cell::RefCell<i32>, //~ ERROR unions cannot contain fields that may need dropping
}
union U4<T> {

View file

@ -1,14 +1,5 @@
error[E0658]: unions with non-`Copy` fields other than `ManuallyDrop<T>`, references, and tuples of such types are unstable
--> $DIR/feature-gate-untagged_unions.rs:29:5
|
LL | a: std::cell::RefCell<i32>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #55149 <https://github.com/rust-lang/rust/issues/55149> for more information
= help: add `#![feature(untagged_unions)]` to the crate attributes to enable
error[E0740]: unions cannot contain fields that may need dropping
--> $DIR/feature-gate-untagged_unions.rs:25:5
--> $DIR/field_checks.rs:25:5
|
LL | a: String,
| ^^^^^^^^^
@ -20,7 +11,19 @@ LL | a: std::mem::ManuallyDrop<String>,
| +++++++++++++++++++++++ +
error[E0740]: unions cannot contain fields that may need dropping
--> $DIR/feature-gate-untagged_unions.rs:33:5
--> $DIR/field_checks.rs:29:5
|
LL | a: std::cell::RefCell<i32>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
|
LL | a: std::mem::ManuallyDrop<std::cell::RefCell<i32>>,
| +++++++++++++++++++++++ +
error[E0740]: unions cannot contain fields that may need dropping
--> $DIR/field_checks.rs:33:5
|
LL | a: T,
| ^^^^
@ -32,7 +35,7 @@ LL | a: std::mem::ManuallyDrop<T>,
| +++++++++++++++++++++++ +
error[E0740]: unions cannot contain fields that may need dropping
--> $DIR/feature-gate-untagged_unions.rs:45:5
--> $DIR/field_checks.rs:45:5
|
LL | nest: U5,
| ^^^^^^^^
@ -45,5 +48,4 @@ LL | nest: std::mem::ManuallyDrop<U5>,
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0658, E0740.
For more information about an error, try `rustc --explain E0658`.
For more information about this error, try `rustc --explain E0740`.

View file

@ -1,5 +1,3 @@
#![feature(untagged_unions)]
union Test {
a: A, //~ ERROR unions cannot contain fields that may need dropping
b: B

View file

@ -1,5 +1,5 @@
error[E0740]: unions cannot contain fields that may need dropping
--> $DIR/issue-41073.rs:4:5
--> $DIR/issue-41073.rs:2:5
|
LL | a: A,
| ^^^^

View file

@ -1,49 +1,69 @@
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0`)
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x`)
--> $DIR/union-borrow-move-parent-sibling.rs:56:13
|
LL | let a = &mut u.x.0;
| ---------- mutable borrow occurs here (via `u.x.0`)
LL | let a = &mut (*u.x).0;
| --- mutable borrow occurs here (via `u.x`)
LL | let b = &u.y;
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x.0` -- occurs here
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x` -- occurs here
LL | use_borrow(a);
| - mutable borrow later used here
|
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0`
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x`
error[E0507]: cannot move out of dereference of `ManuallyDrop<((MockVec<u8>, MockVec<u8>), MockVec<u8>)>`
--> $DIR/union-borrow-move-parent-sibling.rs:62:13
|
LL | let a = u.x.0;
| ^^^^^
| |
| move occurs because value has type `(MockVec<u8>, MockVec<u8>)`, which does not implement the `Copy` trait
| help: consider borrowing here: `&u.x.0`
error[E0382]: use of moved value: `u`
--> $DIR/union-borrow-move-parent-sibling.rs:63:13
--> $DIR/union-borrow-move-parent-sibling.rs:64:13
|
LL | let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
LL | let u = U { x: ManuallyDrop::new(((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
LL | let a = u.x;
| --- value moved here
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:69:13
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x`)
--> $DIR/union-borrow-move-parent-sibling.rs:70:13
|
LL | let a = &mut (u.x.0).0;
| -------------- mutable borrow occurs here (via `u.x.0.0`)
LL | let a = &mut ((*u.x).0).0;
| --- mutable borrow occurs here (via `u.x`)
LL | let b = &u.y;
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x.0.0` -- occurs here
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x` -- occurs here
LL | use_borrow(a);
| - mutable borrow later used here
|
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0.0`
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x`
error[E0382]: use of moved value: `u`
error[E0507]: cannot move out of dereference of `ManuallyDrop<((MockVec<u8>, MockVec<u8>), MockVec<u8>)>`
--> $DIR/union-borrow-move-parent-sibling.rs:76:13
|
LL | let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
LL | let a = (u.x.0).0;
| ^^^^^^^^^
| |
| move occurs because value has type `MockVec<u8>`, which does not implement the `Copy` trait
| help: consider borrowing here: `&(u.x.0).0`
error[E0382]: use of moved value: `u`
--> $DIR/union-borrow-move-parent-sibling.rs:78:13
|
LL | let u = U { x: ManuallyDrop::new(((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 a = u.x;
| --- 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:82:13
--> $DIR/union-borrow-move-parent-sibling.rs:84:13
|
LL | let a = &mut *u.y;
| --- mutable borrow occurs here (via `u.y`)
@ -54,7 +74,7 @@ LL | use_borrow(a);
|
= note: `u.x` is a field of the union `U`, so it overlaps the field `u.y`
error: aborting due to 5 previous errors
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0382, E0502.
Some errors have detailed explanations: E0382, E0502, E0507.
For more information about an error, try `rustc --explain E0382`.

View file

@ -1,10 +1,10 @@
// revisions: mirunsafeck thirunsafeck
// [thirunsafeck]compile-flags: -Z thir-unsafeck
#![feature(untagged_unions)]
#![allow(unused)]
use std::ops::{Deref, DerefMut};
use std::mem::ManuallyDrop;
#[derive(Default)]
struct MockBox<T> {
@ -44,47 +44,49 @@ impl<T> DerefMut for MockVec<T> {
union U {
x: ((MockVec<u8>, MockVec<u8>), MockVec<u8>),
y: MockBox<MockVec<u8>>,
x: ManuallyDrop<((MockVec<u8>, MockVec<u8>), MockVec<u8>)>,
y: ManuallyDrop<MockBox<MockVec<u8>>>,
}
fn use_borrow<T>(_: &T) {}
unsafe fn parent_sibling_borrow() {
let mut u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
let a = &mut u.x.0;
let mut u = U { x: ManuallyDrop::new(((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: ((MockVec::new(), MockVec::new()), MockVec::new()) };
let a = u.x.0;
let u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
let a = u.x.0; //~ERROR cannot move out of dereference
let a = u.x;
let b = u.y; //~ ERROR use of moved value: `u`
}
unsafe fn grandparent_sibling_borrow() {
let mut u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
let a = &mut (u.x.0).0;
let mut u = U { x: ManuallyDrop::new(((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: ((MockVec::new(), MockVec::new()), MockVec::new()) };
let a = (u.x.0).0;
let u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
let a = (u.x.0).0; //~ERROR cannot move out of dereference
let a = u.x;
let b = u.y; //~ ERROR use of moved value: `u`
}
unsafe fn deref_sibling_borrow() {
let mut u = U { y: MockBox::default() };
let mut u = U { y: ManuallyDrop::new(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: ((MockVec::new(), MockVec::new()), MockVec::new()) };
let u = U { x: ManuallyDrop::new(((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,49 +1,69 @@
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0`)
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x`)
--> $DIR/union-borrow-move-parent-sibling.rs:56:13
|
LL | let a = &mut u.x.0;
| ---------- mutable borrow occurs here (via `u.x.0`)
LL | let a = &mut (*u.x).0;
| --- mutable borrow occurs here (via `u.x`)
LL | let b = &u.y;
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x.0` -- occurs here
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x` -- occurs here
LL | use_borrow(a);
| - mutable borrow later used here
|
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0`
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x`
error[E0507]: cannot move out of dereference of `ManuallyDrop<((MockVec<u8>, MockVec<u8>), MockVec<u8>)>`
--> $DIR/union-borrow-move-parent-sibling.rs:62:13
|
LL | let a = u.x.0;
| ^^^^^
| |
| move occurs because value has type `(MockVec<u8>, MockVec<u8>)`, which does not implement the `Copy` trait
| help: consider borrowing here: `&u.x.0`
error[E0382]: use of moved value: `u`
--> $DIR/union-borrow-move-parent-sibling.rs:63:13
--> $DIR/union-borrow-move-parent-sibling.rs:64:13
|
LL | let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
LL | let u = U { x: ManuallyDrop::new(((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
LL | let a = u.x;
| --- value moved here
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:69:13
error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x`)
--> $DIR/union-borrow-move-parent-sibling.rs:70:13
|
LL | let a = &mut (u.x.0).0;
| -------------- mutable borrow occurs here (via `u.x.0.0`)
LL | let a = &mut ((*u.x).0).0;
| --- mutable borrow occurs here (via `u.x`)
LL | let b = &u.y;
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x.0.0` -- occurs here
| ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x` -- occurs here
LL | use_borrow(a);
| - mutable borrow later used here
|
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0.0`
= note: `u.y` is a field of the union `U`, so it overlaps the field `u.x`
error[E0382]: use of moved value: `u`
error[E0507]: cannot move out of dereference of `ManuallyDrop<((MockVec<u8>, MockVec<u8>), MockVec<u8>)>`
--> $DIR/union-borrow-move-parent-sibling.rs:76:13
|
LL | let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) };
LL | let a = (u.x.0).0;
| ^^^^^^^^^
| |
| move occurs because value has type `MockVec<u8>`, which does not implement the `Copy` trait
| help: consider borrowing here: `&(u.x.0).0`
error[E0382]: use of moved value: `u`
--> $DIR/union-borrow-move-parent-sibling.rs:78:13
|
LL | let u = U { x: ManuallyDrop::new(((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 a = u.x;
| --- 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:82:13
--> $DIR/union-borrow-move-parent-sibling.rs:84:13
|
LL | let a = &mut *u.y;
| --- mutable borrow occurs here (via `u.y`)
@ -54,7 +74,7 @@ LL | use_borrow(a);
|
= note: `u.x` is a field of the union `U`, so it overlaps the field `u.y`
error: aborting due to 5 previous errors
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0382, E0502.
Some errors have detailed explanations: E0382, E0502, E0507.
For more information about an error, try `rustc --explain E0382`.

View file

@ -1,19 +0,0 @@
// test for a union with a field that's a union with a manual impl Drop
// Ensures we do not treat all unions as not having any drop glue.
#![feature(untagged_unions)]
union Foo {
bar: Bar, //~ ERROR unions cannot contain fields that may need dropping
}
union Bar {
a: i32,
b: u32,
}
impl Drop for Bar {
fn drop(&mut self) {}
}
fn main() {}

View file

@ -1,15 +0,0 @@
error[E0740]: unions cannot contain fields that may need dropping
--> $DIR/union-custom-drop.rs:7:5
|
LL | bar: Bar,
| ^^^^^^^^
|
= note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
|
LL | bar: std::mem::ManuallyDrop<Bar>,
| +++++++++++++++++++++++ +
error: aborting due to previous error
For more information about this error, try `rustc --explain E0740`.

View file

@ -1,5 +1,5 @@
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:17:14
--> $DIR/union-deref.rs:16:14
|
LL | unsafe { u.f.0 = Vec::new() };
| ^^^
@ -8,7 +8,7 @@ LL | unsafe { u.f.0 = Vec::new() };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:19:19
--> $DIR/union-deref.rs:18:19
|
LL | unsafe { &mut u.f.0 };
| ^^^
@ -17,7 +17,7 @@ LL | unsafe { &mut u.f.0 };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:21:14
--> $DIR/union-deref.rs:20:14
|
LL | unsafe { u.f.0.push(0) };
| ^^^
@ -26,7 +26,7 @@ LL | unsafe { u.f.0.push(0) };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:25:14
--> $DIR/union-deref.rs:24:14
|
LL | unsafe { u.f.0.0 = Vec::new() };
| ^^^^^
@ -35,7 +35,7 @@ LL | unsafe { u.f.0.0 = Vec::new() };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:27:19
--> $DIR/union-deref.rs:26:19
|
LL | unsafe { &mut u.f.0.0 };
| ^^^^^
@ -44,7 +44,7 @@ LL | unsafe { &mut u.f.0.0 };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:29:14
--> $DIR/union-deref.rs:28:14
|
LL | unsafe { u.f.0.0.push(0) };
| ^^^^^

View file

@ -3,7 +3,6 @@
//! Test the part of RFC 2514 that is about not applying `DerefMut` coercions
//! of union fields.
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;

View file

@ -1,5 +1,5 @@
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:17:14
--> $DIR/union-deref.rs:16:14
|
LL | unsafe { u.f.0 = Vec::new() };
| ^^^
@ -8,7 +8,7 @@ LL | unsafe { u.f.0 = Vec::new() };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:19:19
--> $DIR/union-deref.rs:18:19
|
LL | unsafe { &mut u.f.0 };
| ^^^
@ -17,7 +17,7 @@ LL | unsafe { &mut u.f.0 };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:21:14
--> $DIR/union-deref.rs:20:14
|
LL | unsafe { u.f.0.push(0) };
| ^^^
@ -26,7 +26,7 @@ LL | unsafe { u.f.0.push(0) };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:25:14
--> $DIR/union-deref.rs:24:14
|
LL | unsafe { u.f.0.0 = Vec::new() };
| ^^^^^
@ -35,7 +35,7 @@ LL | unsafe { u.f.0.0 = Vec::new() };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:27:19
--> $DIR/union-deref.rs:26:19
|
LL | unsafe { &mut u.f.0.0 };
| ^^^^^
@ -44,7 +44,7 @@ LL | unsafe { &mut u.f.0.0 };
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
--> $DIR/union-deref.rs:29:14
--> $DIR/union-deref.rs:28:14
|
LL | unsafe { u.f.0.0.push(0) };
| ^^^^^

View file

@ -27,7 +27,7 @@ LL | move_out(x.f1_nocopy);
| ^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `x.f1_nocopy` has type `RefCell<i32>`, which does not implement the `Copy` trait
| move occurs because `x.f1_nocopy` has type `ManuallyDrop<RefCell<i32>>`, which does not implement the `Copy` trait
error: aborting due to 3 previous errors

View file

@ -3,20 +3,20 @@
//! Test the behavior of moving out of non-`Copy` union fields.
//! Avoid types that `Drop`, we want to focus on moving.
#![feature(untagged_unions)]
use std::cell::RefCell;
use std::mem::ManuallyDrop;
fn move_out<T>(x: T) {}
union U1 {
f1_nocopy: RefCell<i32>,
f2_nocopy: RefCell<i32>,
f1_nocopy: ManuallyDrop<RefCell<i32>>,
f2_nocopy: ManuallyDrop<RefCell<i32>>,
f3_copy: i32,
}
union U2 {
f1_nocopy: RefCell<i32>,
f1_nocopy: ManuallyDrop<RefCell<i32>>,
}
impl Drop for U2 {
fn drop(&mut self) {}

View file

@ -27,7 +27,7 @@ LL | move_out(x.f1_nocopy);
| ^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `x.f1_nocopy` has type `RefCell<i32>`, which does not implement the `Copy` trait
| move occurs because `x.f1_nocopy` has type `ManuallyDrop<RefCell<i32>>`, which does not implement the `Copy` trait
error: aborting due to 3 previous errors

View file

@ -1,8 +1,7 @@
#![feature(untagged_unions)]
union U { //~ ERROR recursive type `U` has infinite size
a: u8,
b: U,
b: std::mem::ManuallyDrop<U>,
}
fn main() {}

View file

@ -1,16 +1,16 @@
error[E0072]: recursive type `U` has infinite size
--> $DIR/union-nonrepresentable.rs:3:1
--> $DIR/union-nonrepresentable.rs:2:1
|
LL | union U {
| ^^^^^^^ recursive type has infinite size
LL | a: u8,
LL | b: U,
| - recursive without indirection
LL | b: std::mem::ManuallyDrop<U>,
| ------------------------- recursive without indirection
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `U` representable
|
LL | b: Box<U>,
| ++++ +
LL | b: Box<std::mem::ManuallyDrop<U>>,
| ++++ +
error: aborting due to previous error

View file

@ -1,18 +1,18 @@
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
union Foo<T: ?Sized> {
value: T,
value: ManuallyDrop<T>,
//~^ ERROR the size for values of type
}
struct Foo2<T: ?Sized> {
value: T,
value: ManuallyDrop<T>,
//~^ ERROR the size for values of type
t: u32,
}
enum Foo3<T: ?Sized> {
Value(T),
Value(ManuallyDrop<T>),
//~^ ERROR the size for values of type
}

View file

@ -3,9 +3,10 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
|
LL | union Foo<T: ?Sized> {
| - this type parameter needs to be `std::marker::Sized`
LL | value: T,
| ^ doesn't have a size known at compile-time
LL | value: ManuallyDrop<T>,
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= note: required because it appears within the type `ManuallyDrop<T>`
= note: no field of a union may have a dynamically sized type
= help: change the field's type to have a statically known size
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@ -15,21 +16,22 @@ LL + union Foo<T> {
|
help: borrowed types always have a statically known size
|
LL | value: &T,
LL | value: &ManuallyDrop<T>,
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
LL | value: Box<T>,
| ++++ +
LL | value: Box<ManuallyDrop<T>>,
| ++++ +
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/union-sized-field.rs:9:12
|
LL | struct Foo2<T: ?Sized> {
| - this type parameter needs to be `std::marker::Sized`
LL | value: T,
| ^ doesn't have a size known at compile-time
LL | value: ManuallyDrop<T>,
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= note: required because it appears within the type `ManuallyDrop<T>`
= note: only the last field of a struct may have a dynamically sized type
= help: change the field's type to have a statically known size
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@ -39,21 +41,22 @@ LL + struct Foo2<T> {
|
help: borrowed types always have a statically known size
|
LL | value: &T,
LL | value: &ManuallyDrop<T>,
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
LL | value: Box<T>,
| ++++ +
LL | value: Box<ManuallyDrop<T>>,
| ++++ +
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/union-sized-field.rs:15:11
|
LL | enum Foo3<T: ?Sized> {
| - this type parameter needs to be `std::marker::Sized`
LL | Value(T),
| ^ doesn't have a size known at compile-time
LL | Value(ManuallyDrop<T>),
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= note: required because it appears within the type `ManuallyDrop<T>`
= note: no field of an enum variant may have a dynamically sized type
= help: change the field's type to have a statically known size
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@ -63,12 +66,12 @@ LL + enum Foo3<T> {
|
help: borrowed types always have a statically known size
|
LL | Value(&T),
LL | Value(&ManuallyDrop<T>),
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
LL | Value(Box<T>),
| ++++ +
LL | Value(Box<ManuallyDrop<T>>),
| ++++ +
error: aborting due to 3 previous errors

View file

@ -1,5 +1,5 @@
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:34:5
--> $DIR/union-unsafe.rs:33:5
|
LL | *(u.p) = 13;
| ^^^^^^^^^^^ access to union field
@ -7,23 +7,15 @@ LL | *(u.p) = 13;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:39:5
--> $DIR/union-unsafe.rs:38:5
|
LL | u.a = (RefCell::new(0), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:40:5
|
LL | u.a.0 = RefCell::new(0);
| ^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
LL | u.a = (ManuallyDrop::new(RefCell::new(0)), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:47:6
--> $DIR/union-unsafe.rs:46:6
|
LL | *u3.a = T::default();
| ^^^^ access to union field
@ -31,7 +23,7 @@ LL | *u3.a = T::default();
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:53:6
--> $DIR/union-unsafe.rs:52:6
|
LL | *u3.a = T::default();
| ^^^^ access to union field
@ -39,7 +31,7 @@ LL | *u3.a = T::default();
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:61:13
--> $DIR/union-unsafe.rs:60:13
|
LL | let a = u1.a;
| ^^^^ access to union field
@ -47,7 +39,7 @@ LL | let a = u1.a;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:64:14
--> $DIR/union-unsafe.rs:63:14
|
LL | let U1 { a } = u1;
| ^ access to union field
@ -55,7 +47,7 @@ LL | let U1 { a } = u1;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:65:12
--> $DIR/union-unsafe.rs:64:12
|
LL | if let U1 { a: 12 } = u1 {}
| ^^^^^^^^^^^^ access to union field
@ -63,7 +55,7 @@ LL | if let U1 { a: 12 } = u1 {}
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:70:6
--> $DIR/union-unsafe.rs:69:6
|
LL | *u2.a = String::from("new");
| ^^^^ access to union field
@ -71,7 +63,7 @@ LL | *u2.a = String::from("new");
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:74:6
--> $DIR/union-unsafe.rs:73:6
|
LL | *u3.a = 1;
| ^^^^ access to union field
@ -79,13 +71,13 @@ LL | *u3.a = 1;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:78:6
--> $DIR/union-unsafe.rs:77:6
|
LL | *u3.a = String::from("new");
| ^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error: aborting due to 11 previous errors
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0133`.

View file

@ -1,7 +1,6 @@
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck
#![feature(untagged_unions)]
use std::mem::ManuallyDrop;
use std::cell::RefCell;
@ -26,7 +25,7 @@ union URef {
}
union URefCell { // field that does not drop but is not `Copy`, either
a: (RefCell<i32>, i32),
a: (ManuallyDrop<RefCell<i32>>, i32),
}
fn deref_union_field(mut u: URef) {
@ -36,8 +35,8 @@ fn deref_union_field(mut u: URef) {
fn assign_noncopy_union_field(mut u: URefCell) {
// FIXME(thir-unsafeck)
u.a = (RefCell::new(0), 1); //~ ERROR assignment to union field that might need dropping
u.a.0 = RefCell::new(0); //~ ERROR assignment to union field that might need dropping
u.a = (ManuallyDrop::new(RefCell::new(0)), 1); //~ ERROR assignment to union field
u.a.0 = ManuallyDrop::new(RefCell::new(0)); // OK (assignment does not drop)
u.a.1 = 1; // OK
}

View file

@ -1,5 +1,5 @@
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:34:6
--> $DIR/union-unsafe.rs:33:6
|
LL | *(u.p) = 13;
| ^^^^^ access to union field
@ -7,23 +7,15 @@ LL | *(u.p) = 13;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:39:5
--> $DIR/union-unsafe.rs:38:5
|
LL | u.a = (RefCell::new(0), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:40:5
|
LL | u.a.0 = RefCell::new(0);
| ^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
LL | u.a = (ManuallyDrop::new(RefCell::new(0)), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:47:6
--> $DIR/union-unsafe.rs:46:6
|
LL | *u3.a = T::default();
| ^^^^ access to union field
@ -31,7 +23,7 @@ LL | *u3.a = T::default();
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:53:6
--> $DIR/union-unsafe.rs:52:6
|
LL | *u3.a = T::default();
| ^^^^ access to union field
@ -39,7 +31,7 @@ LL | *u3.a = T::default();
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:61:13
--> $DIR/union-unsafe.rs:60:13
|
LL | let a = u1.a;
| ^^^^ access to union field
@ -47,7 +39,7 @@ LL | let a = u1.a;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:64:14
--> $DIR/union-unsafe.rs:63:14
|
LL | let U1 { a } = u1;
| ^ access to union field
@ -55,7 +47,7 @@ LL | let U1 { a } = u1;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:65:8
--> $DIR/union-unsafe.rs:64:8
|
LL | if let U1 { a: 12 } = u1 {}
| ^^^^^^^^^^^^^^^^^^^^^ access to union field
@ -63,7 +55,7 @@ LL | if let U1 { a: 12 } = u1 {}
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:70:6
--> $DIR/union-unsafe.rs:69:6
|
LL | *u2.a = String::from("new");
| ^^^^ access to union field
@ -71,7 +63,7 @@ LL | *u2.a = String::from("new");
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:74:6
--> $DIR/union-unsafe.rs:73:6
|
LL | *u3.a = 1;
| ^^^^ access to union field
@ -79,13 +71,13 @@ LL | *u3.a = 1;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-unsafe.rs:78:6
--> $DIR/union-unsafe.rs:77:6
|
LL | *u3.a = String::from("new");
| ^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error: aborting due to 11 previous errors
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0133`.

View file

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/union-unsized.rs:7:8
--> $DIR/union-unsized.rs:5:8
|
LL | a: str,
| ^^^ doesn't have a size known at compile-time
@ -17,7 +17,7 @@ LL | a: Box<str>,
| ++++ +
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/union-unsized.rs:15:8
--> $DIR/union-unsized.rs:13:8
|
LL | b: str,
| ^^^ doesn't have a size known at compile-time

View file

@ -1,8 +1,6 @@
// revisions: mirunsafeck thirunsafeck
// [thirunsafeck]compile-flags: -Z thir-unsafeck
#![feature(untagged_unions)]
union U {
a: str,
//~^ ERROR the size for values of type

View file

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/union-unsized.rs:7:8
--> $DIR/union-unsized.rs:5:8
|
LL | a: str,
| ^^^ doesn't have a size known at compile-time
@ -17,7 +17,7 @@ LL | a: Box<str>,
| ++++ +
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/union-unsized.rs:15:8
--> $DIR/union-unsized.rs:13:8
|
LL | b: str,
| ^^^ doesn't have a size known at compile-time

View file

@ -1,5 +1,5 @@
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:20:5
--> $DIR/union-assignop.rs:19:5
|
LL | foo.a += 5;
| ^^^^^^^^^^ access to union field
@ -7,20 +7,20 @@ LL | foo.a += 5;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:21:5
--> $DIR/union-assignop.rs:20:6
|
LL | foo.b += Dropping;
| ^^^^^ access to union field
LL | *foo.b += NonCopy;
| ^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:22:5
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:21:6
|
LL | foo.b = Dropping;
| ^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
LL | *foo.b = NonCopy;
| ^^^^^ access to union field
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:23:5
@ -46,14 +46,6 @@ LL | foo.b = foo.b;
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:27:5
|
LL | foo.b = foo.b;
| ^^^^^^^^^^^^^ assignment to union field that might need dropping
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
error: aborting due to 7 previous errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0133`.

View file

@ -1,30 +1,29 @@
// revisions: mirunsafeck thirunsafeck
// [thirunsafeck]compile-flags: -Z thir-unsafeck
#![feature(untagged_unions)]
use std::ops::AddAssign;
use std::mem::ManuallyDrop;
struct Dropping;
impl AddAssign for Dropping {
struct NonCopy;
impl AddAssign for NonCopy {
fn add_assign(&mut self, _: Self) {}
}
union Foo {
a: u8, // non-dropping
b: Dropping, // treated as dropping
b: ManuallyDrop<NonCopy>,
}
fn main() {
let mut foo = Foo { a: 42 };
foo.a += 5; //~ ERROR access to union field is unsafe
foo.b += Dropping; //~ ERROR access to union field is unsafe
foo.b = Dropping; //~ ERROR assignment to union field that might need dropping is unsafe
*foo.b += NonCopy; //~ ERROR access to union field is unsafe
*foo.b = NonCopy; //~ ERROR access to union field is unsafe
foo.b = ManuallyDrop::new(NonCopy);
foo.a; //~ ERROR access to union field is unsafe
let foo = Foo { a: 42 };
foo.b; //~ ERROR access to union field is unsafe
let mut foo = Foo { a: 42 };
foo.b = foo.b;
//~^ ERROR access to union field is unsafe
//~| ERROR assignment to union field that might need dropping
}

View file

@ -1,5 +1,5 @@
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:20:5
--> $DIR/union-assignop.rs:19:5
|
LL | foo.a += 5;
| ^^^^^ access to union field
@ -7,20 +7,20 @@ LL | foo.a += 5;
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:21:5
--> $DIR/union-assignop.rs:20:6
|
LL | foo.b += Dropping;
| ^^^^^ access to union field
LL | *foo.b += NonCopy;
| ^^^^^ access to union field
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:22:5
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:21:6
|
LL | foo.b = Dropping;
| ^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
LL | *foo.b = NonCopy;
| ^^^^^ access to union field
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:23:5
@ -38,14 +38,6 @@ LL | foo.b;
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:27:5
|
LL | foo.b = foo.b;
| ^^^^^^^^^^^^^ assignment to union field that might need dropping
|
= note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/union-assignop.rs:27:13
|
@ -54,6 +46,6 @@ LL | foo.b = foo.b;
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
error: aborting due to 7 previous errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0133`.

View file

@ -2,8 +2,6 @@
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck
#![feature(untagged_unions)]
union Foo {
bar: i8,
_blah: isize,

View file

@ -1,19 +1,19 @@
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck
#![feature(untagged_unions)]
union Foo {
bar: i8,
zst: (),
pizza: Pizza,
}
#[derive(Clone, Copy)]
struct Pizza {
topping: Option<PizzaTopping>
}
#[allow(dead_code)]
#[derive(Clone, Copy)]
enum PizzaTopping {
Cheese,
Pineapple,