From 5bf6017b872bec43db353017f7915d3145ce5f5d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 29 Jun 2022 22:33:18 -0400 Subject: [PATCH] remove untagged_union feature gate --- compiler/rustc_feature/src/active.rs | 7 -- compiler/rustc_feature/src/removed.rs | 3 + compiler/rustc_passes/src/stability.rs | 68 +------------------ compiler/rustc_typeck/src/check/check.rs | 35 +++++++++- .../ui/associated-type-bounds/duplicate.rs | 14 ++-- .../ui/associated-type-bounds/inside-adt.rs | 9 +-- .../associated-type-bounds/inside-adt.stderr | 64 ++++++++--------- .../ui/associated-type-bounds/union-bounds.rs | 1 - .../ui/binding/issue-53114-safety-checks.rs | 4 +- .../ui/borrowck/borrowck-union-move-assign.rs | 16 ++--- .../borrowck-union-move-assign.stderr | 2 +- src/test/ui/borrowck/borrowck-union-move.rs | 14 ++-- .../ui/borrowck/borrowck-union-move.stderr | 6 +- .../move-from-union-field-issue-66500.rs | 2 - .../move-from-union-field-issue-66500.stderr | 8 +-- src/test/ui/consts/invalid-union.64bit.stderr | 6 +- src/test/ui/consts/invalid-union.rs | 5 +- src/test/ui/consts/qualif-union.rs | 13 ++-- src/test/ui/consts/qualif-union.stderr | 10 +-- .../feature-gate-associated_type_bounds.rs | 8 +-- src/test/ui/nll/issue-55651.rs | 14 ++-- .../ui/repr/repr-packed-contains-align.rs | 5 +- .../ui/repr/repr-packed-contains-align.stderr | 40 +++++------ .../rfc-2093-infer-outlives/explicit-union.rs | 2 +- .../explicit-union.stderr | 2 +- .../rfc-2093-infer-outlives/nested-union.rs | 2 +- .../nested-union.stderr | 2 +- .../field_checks.rs} | 4 +- .../field_checks.stderr} | 30 ++++---- src/test/ui/union/issue-41073.rs | 2 - src/test/ui/union/issue-41073.stderr | 2 +- ...row-move-parent-sibling.mirunsafeck.stderr | 60 ++++++++++------ .../union/union-borrow-move-parent-sibling.rs | 28 ++++---- ...ow-move-parent-sibling.thirunsafeck.stderr | 60 ++++++++++------ src/test/ui/union/union-custom-drop.rs | 19 ------ src/test/ui/union/union-custom-drop.stderr | 15 ---- .../ui/union/union-deref.mirunsafeck.stderr | 12 ++-- src/test/ui/union/union-deref.rs | 1 - .../ui/union/union-deref.thirunsafeck.stderr | 12 ++-- .../ui/union/union-move.mirunsafeck.stderr | 2 +- src/test/ui/union/union-move.rs | 8 +-- .../ui/union/union-move.thirunsafeck.stderr | 2 +- src/test/ui/union/union-nonrepresentable.rs | 3 +- .../ui/union/union-nonrepresentable.stderr | 10 +-- src/test/ui/union/union-sized-field.rs | 8 +-- src/test/ui/union/union-sized-field.stderr | 33 +++++---- src/test/ui/union/union-unsafe.mir.stderr | 34 ++++------ src/test/ui/union/union-unsafe.rs | 7 +- src/test/ui/union/union-unsafe.thir.stderr | 34 ++++------ .../ui/union/union-unsized.mirunsafeck.stderr | 4 +- src/test/ui/union/union-unsized.rs | 2 - .../union/union-unsized.thirunsafeck.stderr | 4 +- .../unsafe/union-assignop.mirunsafeck.stderr | 28 +++----- src/test/ui/unsafe/union-assignop.rs | 15 ++-- .../unsafe/union-assignop.thirunsafeck.stderr | 28 +++----- src/test/ui/unsafe/union-modification.rs | 2 - src/test/ui/unsafe/union.rs | 4 +- 57 files changed, 386 insertions(+), 449 deletions(-) rename src/test/ui/{feature-gates/feature-gate-untagged_unions.rs => union/field_checks.rs} (82%) rename src/test/ui/{feature-gates/feature-gate-untagged_unions.stderr => union/field_checks.stderr} (69%) delete mode 100644 src/test/ui/union/union-custom-drop.rs delete mode 100644 src/test/ui/union/union-custom-drop.stderr diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 117bdad971a..1fc4d09eb0a 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -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` diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 54626caaf53..3b0f9a65e07 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -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. diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index fa52c62b00c..a06213ca5f4 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -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`, \ - 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); diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 79edbeab9c7..9c522807bf6 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -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 { diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index e1dc6f8f4b6..6e464f69510 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -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> { //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] @@ -74,36 +74,36 @@ where union UI1> { //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] - f: T, + f: ManuallyDrop, } union UI2> { //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] - f: T, + f: ManuallyDrop, } union UI3> { //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] - f: T, + f: ManuallyDrop, } union UW1 where T: Iterator, //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] { - f: T, + f: ManuallyDrop, } union UW2 where T: Iterator, //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] { - f: T, + f: ManuallyDrop, } union UW3 where T: Iterator, //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719] { - f: T, + f: ManuallyDrop, } fn FI1>() {} diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs index 5af05738750..f26037f0707 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.rs +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -1,5 +1,6 @@ #![feature(associated_type_bounds)] -#![feature(untagged_unions)] + +use std::mem::ManuallyDrop; struct S1 { f: dyn Iterator } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions @@ -17,12 +18,12 @@ enum E3 { V(dyn Iterator) } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions //~| ERROR the size for values of type `(dyn Iterator + 'static)` -union U1 { f: dyn Iterator } +union U1 { f: ManuallyDrop> } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions //~| ERROR the size for values of type `(dyn Iterator + 'static)` -union U2 { f: Box> } +union U2 { f: ManuallyDrop>> } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions -union U3 { f: dyn Iterator } +union U3 { f: ManuallyDrop> } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions //~| ERROR the size for values of type `(dyn Iterator + 'static)` diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr index 0cacd787247..978390fa712 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.stderr +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -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 } | ^^^^^^^^^^ 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> } | ^^^^^^^^^^ 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 } | ^^^^^^^^^^^^^ 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) } | ^^^^^^^^^^ 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>) } | ^^^^^^^^^^ 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) } | ^^^^^^^^^^^^^ 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 } - | ^^^^^^^^^^ +LL | union U1 { f: ManuallyDrop> } + | ^^^^^^^^^^ 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> } - | ^^^^^^^^^^ +LL | union U2 { f: ManuallyDrop>> } + | ^^^^^^^^^^ 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 } - | ^^^^^^^^^^^^^ +LL | union U3 { f: ManuallyDrop> } + | ^^^^^^^^^^^^^ error[E0277]: the size for values of type `(dyn Iterator + '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) } | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -71,7 +71,7 @@ LL | enum E1 { V(Box>) } | ++++ + error[E0277]: the size for values of type `(dyn Iterator + '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) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -89,40 +89,42 @@ LL | enum E3 { V(Box>) } | ++++ + error[E0277]: the size for values of type `(dyn Iterator + '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 } - | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time +LL | union U1 { f: ManuallyDrop> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = help: within `ManuallyDrop<(dyn Iterator + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: required because it appears within the type `ManuallyDrop<(dyn Iterator + '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 } +LL | union U1 { f: &ManuallyDrop> } | + help: the `Box` type always has a statically known size and allocates its contents in the heap | -LL | union U1 { f: Box> } - | ++++ + +LL | union U1 { f: Box>> } + | ++++ + error[E0277]: the size for values of type `(dyn Iterator + '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 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time +LL | union U3 { f: ManuallyDrop> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = help: within `ManuallyDrop<(dyn Iterator + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: required because it appears within the type `ManuallyDrop<(dyn Iterator + '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 } +LL | union U3 { f: &ManuallyDrop> } | + help: the `Box` type always has a statically known size and allocates its contents in the heap | -LL | union U3 { f: Box> } - | ++++ + +LL | union U3 { f: Box>> } + | ++++ + error: aborting due to 13 previous errors diff --git a/src/test/ui/associated-type-bounds/union-bounds.rs b/src/test/ui/associated-type-bounds/union-bounds.rs index 97c5acf1f72..46e5aef0403 100644 --- a/src/test/ui/associated-type-bounds/union-bounds.rs +++ b/src/test/ui/associated-type-bounds/union-bounds.rs @@ -1,7 +1,6 @@ // run-pass #![feature(associated_type_bounds)] -#![feature(untagged_unions)] #![allow(unused_assignments)] diff --git a/src/test/ui/binding/issue-53114-safety-checks.rs b/src/test/ui/binding/issue-53114-safety-checks.rs index 5042ad024af..d0eb28c5714 100644 --- a/src/test/ui/binding/issue-53114-safety-checks.rs +++ b/src/test/ui/binding/issue-53114-safety-checks.rs @@ -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 } diff --git a/src/test/ui/borrowck/borrowck-union-move-assign.rs b/src/test/ui/borrowck/borrowck-union-move-assign.rs index a24f42d2ddf..4c96ccdb25a 100644 --- a/src/test/ui/borrowck/borrowck-union-move-assign.rs +++ b/src/test/ui/borrowck/borrowck-union-move-assign.rs @@ -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, + b: ManuallyDrop, } 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 } } diff --git a/src/test/ui/borrowck/borrowck-union-move-assign.stderr b/src/test/ui/borrowck/borrowck-union-move-assign.stderr index 0b1714fd75d..af6f6fac408 100644 --- a/src/test/ui/borrowck/borrowck-union-move-assign.stderr +++ b/src/test/ui/borrowck/borrowck-union-move-assign.stderr @@ -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 diff --git a/src/test/ui/borrowck/borrowck-union-move.rs b/src/test/ui/borrowck/borrowck-union-move.rs index d0aa6dff744..510547ad5bb 100644 --- a/src/test/ui/borrowck/borrowck-union-move.rs +++ b/src/test/ui/borrowck/borrowck-union-move.rs @@ -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, + n2: ManuallyDrop, } union Ucc { c1: Copy, @@ -14,24 +14,24 @@ union Ucc { } union Ucn { c: Copy, - n: NonCopy, + n: ManuallyDrop, } 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` } diff --git a/src/test/ui/borrowck/borrowck-union-move.stderr b/src/test/ui/borrowck/borrowck-union-move.stderr index abbb0142a9c..731607fbdd1 100644 --- a/src/test/ui/borrowck/borrowck-union-move.stderr +++ b/src/test/ui/borrowck/borrowck-union-move.stderr @@ -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 diff --git a/src/test/ui/borrowck/move-from-union-field-issue-66500.rs b/src/test/ui/borrowck/move-from-union-field-issue-66500.rs index 8fbf120fc1c..0bd2147f463 100644 --- a/src/test/ui/borrowck/move-from-union-field-issue-66500.rs +++ b/src/test/ui/borrowck/move-from-union-field-issue-66500.rs @@ -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, diff --git a/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr b/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr index 82c3fe3b12d..70078582713 100644 --- a/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr +++ b/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr @@ -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 diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index 81c10244249..d50e74a16ec 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -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 ..y..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 diff --git a/src/test/ui/consts/invalid-union.rs b/src/test/ui/consts/invalid-union.rs index f3f1af89b2c..efeddf75cb5 100644 --- a/src/test/ui/consts/invalid-union.rs +++ b/src/test/ui/consts/invalid-union.rs @@ -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, + cell: ManuallyDrop>, } const C: S = { diff --git a/src/test/ui/consts/qualif-union.rs b/src/test/ui/consts/qualif-union.rs index 2054b5b89ed..11c019be964 100644 --- a/src/test/ui/consts/qualif-union.rs +++ b/src/test/ui/consts/qualif-union.rs @@ -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 } +union U { i: u32, c: ManuallyDrop> } -const C1: Cell = { - unsafe { U { c: Cell::new(0) }.c } +const C1: ManuallyDrop> = { + unsafe { U { c: ManuallyDrop::new(Cell::new(0)) }.c } }; -const C2: Cell = { +const C2: ManuallyDrop> = { unsafe { U { i : 0 }.c } }; -const C3: Cell = { +const C3: ManuallyDrop> = { let mut u = U { i: 0 }; u.i = 1; unsafe { u.c } diff --git a/src/test/ui/consts/qualif-union.stderr b/src/test/ui/consts/qualif-union.stderr index fda8ad4a3bc..8ec68ada048 100644 --- a/src/test/ui/consts/qualif-union.stderr +++ b/src/test/ui/consts/qualif-union.stderr @@ -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 diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs index a93fb797713..4e020327447 100644 --- a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -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> { union _Un1> { //~^ ERROR associated type bounds are unstable - outest: std::mem::ManuallyDrop, - outer: T::As1, - inner: ::As2, + outest: ManuallyDrop, + outer: ManuallyDrop, + inner: ManuallyDrop<::As2>, } type _TaWhere1 where T: Iterator = T; diff --git a/src/test/ui/nll/issue-55651.rs b/src/test/ui/nll/issue-55651.rs index 46255bf74a1..75ba4827174 100644 --- a/src/test/ui/nll/issue-55651.rs +++ b/src/test/ui/nll/issue-55651.rs @@ -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, + b: ManuallyDrop, } 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 } } diff --git a/src/test/ui/repr/repr-packed-contains-align.rs b/src/test/ui/repr/repr-packed-contains-align.rs index 67d87eb5cd5..bef5c7d8c62 100644 --- a/src/test/ui/repr/repr-packed-contains-align.rs +++ b/src/test/ui/repr/repr-packed-contains-align.rs @@ -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 } diff --git a/src/test/ui/repr/repr-packed-contains-align.stderr b/src/test/ui/repr/repr-packed-contains-align.stderr index 531004e8e20..4c3a960cad2 100644 --- a/src/test/ui/repr/repr-packed-contains-align.stderr +++ b/src/test/ui/repr/repr-packed-contains-align.stderr @@ -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); | ^^ diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs b/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs index ea8a3c177e9..871208b5ba7 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-union.rs @@ -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, diff --git a/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr b/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr index 2c6d06aa8c7..16b64bdc29d 100644 --- a/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/explicit-union.stderr @@ -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> { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2093-infer-outlives/nested-union.rs b/src/test/ui/rfc-2093-infer-outlives/nested-union.rs index 0da3cc2ba1b..27ebd0b54db 100644 --- a/src/test/ui/rfc-2093-infer-outlives/nested-union.rs +++ b/src/test/ui/rfc-2093-infer-outlives/nested-union.rs @@ -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 } diff --git a/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr b/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr index 0116a2a68ce..a785c63ce3d 100644 --- a/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/nested-union.stderr @@ -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> { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.rs b/src/test/ui/union/field_checks.rs similarity index 82% rename from src/test/ui/feature-gates/feature-gate-untagged_unions.rs rename to src/test/ui/union/field_checks.rs index a3c05efe666..216f7372a1c 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.rs +++ b/src/test/ui/union/field_checks.rs @@ -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, //~ ERROR unions with non-`Copy` fields other than `ManuallyDrop`, references, and tuples of such types are unstable +union U32 { // field that does not drop but is not `Copy`, either + a: std::cell::RefCell, //~ ERROR unions cannot contain fields that may need dropping } union U4 { diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr b/src/test/ui/union/field_checks.stderr similarity index 69% rename from src/test/ui/feature-gates/feature-gate-untagged_unions.stderr rename to src/test/ui/union/field_checks.stderr index 038b85a60fc..0e0e545b01a 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr +++ b/src/test/ui/union/field_checks.stderr @@ -1,14 +1,5 @@ -error[E0658]: unions with non-`Copy` fields other than `ManuallyDrop`, references, and tuples of such types are unstable - --> $DIR/feature-gate-untagged_unions.rs:29:5 - | -LL | a: std::cell::RefCell, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #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, | +++++++++++++++++++++++ + 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, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>, + | +++++++++++++++++++++++ + + +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, | +++++++++++++++++++++++ + 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, 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`. diff --git a/src/test/ui/union/issue-41073.rs b/src/test/ui/union/issue-41073.rs index 80474b807e7..4dfdc606bb4 100644 --- a/src/test/ui/union/issue-41073.rs +++ b/src/test/ui/union/issue-41073.rs @@ -1,5 +1,3 @@ -#![feature(untagged_unions)] - union Test { a: A, //~ ERROR unions cannot contain fields that may need dropping b: B diff --git a/src/test/ui/union/issue-41073.stderr b/src/test/ui/union/issue-41073.stderr index 7d4208b10da..b3887fa0f90 100644 --- a/src/test/ui/union/issue-41073.stderr +++ b/src/test/ui/union/issue-41073.stderr @@ -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, | ^^^^ diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.mirunsafeck.stderr b/src/test/ui/union/union-borrow-move-parent-sibling.mirunsafeck.stderr index e785a2ee733..ca02de4c61b 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.mirunsafeck.stderr +++ b/src/test/ui/union/union-borrow-move-parent-sibling.mirunsafeck.stderr @@ -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, MockVec), MockVec)>` + --> $DIR/union-borrow-move-parent-sibling.rs:62:13 + | +LL | let a = u.x.0; + | ^^^^^ + | | + | move occurs because value has type `(MockVec, MockVec)`, 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, MockVec), MockVec)>` --> $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`, 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`. diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.rs b/src/test/ui/union/union-borrow-move-parent-sibling.rs index e56d87255db..83781c5e550 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.rs +++ b/src/test/ui/union/union-borrow-move-parent-sibling.rs @@ -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 { @@ -44,47 +44,49 @@ impl DerefMut for MockVec { union U { - x: ((MockVec, MockVec), MockVec), - y: MockBox>, + x: ManuallyDrop<((MockVec, MockVec), MockVec)>, + y: ManuallyDrop>>, } fn use_borrow(_: &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` diff --git a/src/test/ui/union/union-borrow-move-parent-sibling.thirunsafeck.stderr b/src/test/ui/union/union-borrow-move-parent-sibling.thirunsafeck.stderr index e785a2ee733..ca02de4c61b 100644 --- a/src/test/ui/union/union-borrow-move-parent-sibling.thirunsafeck.stderr +++ b/src/test/ui/union/union-borrow-move-parent-sibling.thirunsafeck.stderr @@ -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, MockVec), MockVec)>` + --> $DIR/union-borrow-move-parent-sibling.rs:62:13 + | +LL | let a = u.x.0; + | ^^^^^ + | | + | move occurs because value has type `(MockVec, MockVec)`, 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, MockVec), MockVec)>` --> $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`, 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`. diff --git a/src/test/ui/union/union-custom-drop.rs b/src/test/ui/union/union-custom-drop.rs deleted file mode 100644 index 4b333631ec0..00000000000 --- a/src/test/ui/union/union-custom-drop.rs +++ /dev/null @@ -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() {} diff --git a/src/test/ui/union/union-custom-drop.stderr b/src/test/ui/union/union-custom-drop.stderr deleted file mode 100644 index b5579eeef09..00000000000 --- a/src/test/ui/union/union-custom-drop.stderr +++ /dev/null @@ -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, - | +++++++++++++++++++++++ + - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0740`. diff --git a/src/test/ui/union/union-deref.mirunsafeck.stderr b/src/test/ui/union/union-deref.mirunsafeck.stderr index ff37e6fd917..be5e60ab88a 100644 --- a/src/test/ui/union/union-deref.mirunsafeck.stderr +++ b/src/test/ui/union/union-deref.mirunsafeck.stderr @@ -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) }; | ^^^^^ diff --git a/src/test/ui/union/union-deref.rs b/src/test/ui/union/union-deref.rs index 4bf2ba2f1bf..5aa28d93f96 100644 --- a/src/test/ui/union/union-deref.rs +++ b/src/test/ui/union/union-deref.rs @@ -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; diff --git a/src/test/ui/union/union-deref.thirunsafeck.stderr b/src/test/ui/union/union-deref.thirunsafeck.stderr index ff37e6fd917..be5e60ab88a 100644 --- a/src/test/ui/union/union-deref.thirunsafeck.stderr +++ b/src/test/ui/union/union-deref.thirunsafeck.stderr @@ -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) }; | ^^^^^ diff --git a/src/test/ui/union/union-move.mirunsafeck.stderr b/src/test/ui/union/union-move.mirunsafeck.stderr index f55fbea6336..53050cf539e 100644 --- a/src/test/ui/union/union-move.mirunsafeck.stderr +++ b/src/test/ui/union/union-move.mirunsafeck.stderr @@ -27,7 +27,7 @@ LL | move_out(x.f1_nocopy); | ^^^^^^^^^^^ | | | cannot move out of here - | move occurs because `x.f1_nocopy` has type `RefCell`, which does not implement the `Copy` trait + | move occurs because `x.f1_nocopy` has type `ManuallyDrop>`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/union/union-move.rs b/src/test/ui/union/union-move.rs index 8f78c30d67a..b8b1ac8046a 100644 --- a/src/test/ui/union/union-move.rs +++ b/src/test/ui/union/union-move.rs @@ -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(x: T) {} union U1 { - f1_nocopy: RefCell, - f2_nocopy: RefCell, + f1_nocopy: ManuallyDrop>, + f2_nocopy: ManuallyDrop>, f3_copy: i32, } union U2 { - f1_nocopy: RefCell, + f1_nocopy: ManuallyDrop>, } impl Drop for U2 { fn drop(&mut self) {} diff --git a/src/test/ui/union/union-move.thirunsafeck.stderr b/src/test/ui/union/union-move.thirunsafeck.stderr index f55fbea6336..53050cf539e 100644 --- a/src/test/ui/union/union-move.thirunsafeck.stderr +++ b/src/test/ui/union/union-move.thirunsafeck.stderr @@ -27,7 +27,7 @@ LL | move_out(x.f1_nocopy); | ^^^^^^^^^^^ | | | cannot move out of here - | move occurs because `x.f1_nocopy` has type `RefCell`, which does not implement the `Copy` trait + | move occurs because `x.f1_nocopy` has type `ManuallyDrop>`, which does not implement the `Copy` trait error: aborting due to 3 previous errors diff --git a/src/test/ui/union/union-nonrepresentable.rs b/src/test/ui/union/union-nonrepresentable.rs index 4dbd97ea957..afa73857ac2 100644 --- a/src/test/ui/union/union-nonrepresentable.rs +++ b/src/test/ui/union/union-nonrepresentable.rs @@ -1,8 +1,7 @@ -#![feature(untagged_unions)] union U { //~ ERROR recursive type `U` has infinite size a: u8, - b: U, + b: std::mem::ManuallyDrop, } fn main() {} diff --git a/src/test/ui/union/union-nonrepresentable.stderr b/src/test/ui/union/union-nonrepresentable.stderr index 7da7c870e70..a2380d8bc0e 100644 --- a/src/test/ui/union/union-nonrepresentable.stderr +++ b/src/test/ui/union/union-nonrepresentable.stderr @@ -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, + | ------------------------- recursive without indirection | help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `U` representable | -LL | b: Box, - | ++++ + +LL | b: Box>, + | ++++ + error: aborting due to previous error diff --git a/src/test/ui/union/union-sized-field.rs b/src/test/ui/union/union-sized-field.rs index b84cb3eff56..cb852eff0c6 100644 --- a/src/test/ui/union/union-sized-field.rs +++ b/src/test/ui/union/union-sized-field.rs @@ -1,18 +1,18 @@ -#![feature(untagged_unions)] +use std::mem::ManuallyDrop; union Foo { - value: T, + value: ManuallyDrop, //~^ ERROR the size for values of type } struct Foo2 { - value: T, + value: ManuallyDrop, //~^ ERROR the size for values of type t: u32, } enum Foo3 { - Value(T), + Value(ManuallyDrop), //~^ ERROR the size for values of type } diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index 3fe6e71f3b8..771e8f26199 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -3,9 +3,10 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim | LL | union Foo { | - this type parameter needs to be `std::marker::Sized` -LL | value: T, - | ^ doesn't have a size known at compile-time +LL | value: ManuallyDrop, + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | + = note: required because it appears within the type `ManuallyDrop` = 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 { | help: borrowed types always have a statically known size | -LL | value: &T, +LL | value: &ManuallyDrop, | + help: the `Box` type always has a statically known size and allocates its contents in the heap | -LL | value: Box, - | ++++ + +LL | value: Box>, + | ++++ + 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 { | - this type parameter needs to be `std::marker::Sized` -LL | value: T, - | ^ doesn't have a size known at compile-time +LL | value: ManuallyDrop, + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | + = note: required because it appears within the type `ManuallyDrop` = 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 { | help: borrowed types always have a statically known size | -LL | value: &T, +LL | value: &ManuallyDrop, | + help: the `Box` type always has a statically known size and allocates its contents in the heap | -LL | value: Box, - | ++++ + +LL | value: Box>, + | ++++ + 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 { | - this type parameter needs to be `std::marker::Sized` -LL | Value(T), - | ^ doesn't have a size known at compile-time +LL | Value(ManuallyDrop), + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | + = note: required because it appears within the type `ManuallyDrop` = 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 { | help: borrowed types always have a statically known size | -LL | Value(&T), +LL | Value(&ManuallyDrop), | + help: the `Box` type always has a statically known size and allocates its contents in the heap | -LL | Value(Box), - | ++++ + +LL | Value(Box>), + | ++++ + error: aborting due to 3 previous errors diff --git a/src/test/ui/union/union-unsafe.mir.stderr b/src/test/ui/union/union-unsafe.mir.stderr index 318b00ddea9..0aefa21c944 100644 --- a/src/test/ui/union/union-unsafe.mir.stderr +++ b/src/test/ui/union/union-unsafe.mir.stderr @@ -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`. diff --git a/src/test/ui/union/union-unsafe.rs b/src/test/ui/union/union-unsafe.rs index 3cb3a18cb75..7e9d9052a67 100644 --- a/src/test/ui/union/union-unsafe.rs +++ b/src/test/ui/union/union-unsafe.rs @@ -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), + a: (ManuallyDrop>, 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 } diff --git a/src/test/ui/union/union-unsafe.thir.stderr b/src/test/ui/union/union-unsafe.thir.stderr index a8c3886657f..dbfd92f05d9 100644 --- a/src/test/ui/union/union-unsafe.thir.stderr +++ b/src/test/ui/union/union-unsafe.thir.stderr @@ -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`. diff --git a/src/test/ui/union/union-unsized.mirunsafeck.stderr b/src/test/ui/union/union-unsized.mirunsafeck.stderr index 36e782ac042..59ab835fba2 100644 --- a/src/test/ui/union/union-unsized.mirunsafeck.stderr +++ b/src/test/ui/union/union-unsized.mirunsafeck.stderr @@ -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, | ++++ + 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 diff --git a/src/test/ui/union/union-unsized.rs b/src/test/ui/union/union-unsized.rs index e9792f527dc..8e897d7d3c6 100644 --- a/src/test/ui/union/union-unsized.rs +++ b/src/test/ui/union/union-unsized.rs @@ -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 diff --git a/src/test/ui/union/union-unsized.thirunsafeck.stderr b/src/test/ui/union/union-unsized.thirunsafeck.stderr index 36e782ac042..59ab835fba2 100644 --- a/src/test/ui/union/union-unsized.thirunsafeck.stderr +++ b/src/test/ui/union/union-unsized.thirunsafeck.stderr @@ -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, | ++++ + 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 diff --git a/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr b/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr index cd338ac9e3a..0ecd5203dd9 100644 --- a/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr +++ b/src/test/ui/unsafe/union-assignop.mirunsafeck.stderr @@ -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`. diff --git a/src/test/ui/unsafe/union-assignop.rs b/src/test/ui/unsafe/union-assignop.rs index c4be20aa567..5e667cd10d5 100644 --- a/src/test/ui/unsafe/union-assignop.rs +++ b/src/test/ui/unsafe/union-assignop.rs @@ -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, } 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 } diff --git a/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr b/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr index 71de421a255..24b357e762b 100644 --- a/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr +++ b/src/test/ui/unsafe/union-assignop.thirunsafeck.stderr @@ -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`. diff --git a/src/test/ui/unsafe/union-modification.rs b/src/test/ui/unsafe/union-modification.rs index 5c70b78df7c..9a53ef90852 100644 --- a/src/test/ui/unsafe/union-modification.rs +++ b/src/test/ui/unsafe/union-modification.rs @@ -2,8 +2,6 @@ // revisions: mir thir // [thir]compile-flags: -Z thir-unsafeck -#![feature(untagged_unions)] - union Foo { bar: i8, _blah: isize, diff --git a/src/test/ui/unsafe/union.rs b/src/test/ui/unsafe/union.rs index 5fe09933cfc..4338d78eabb 100644 --- a/src/test/ui/unsafe/union.rs +++ b/src/test/ui/unsafe/union.rs @@ -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 } #[allow(dead_code)] +#[derive(Clone, Copy)] enum PizzaTopping { Cheese, Pineapple,