remove untagged_union feature gate
This commit is contained in:
parent
6dfede3b9d
commit
5bf6017b87
57 changed files with 386 additions and 449 deletions
|
@ -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`
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>>() {}
|
||||
|
|
|
@ -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)`
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
#![allow(unused_assignments)]
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
| ^^
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -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> {
|
|
@ -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`.
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(untagged_unions)]
|
||||
|
||||
union Test {
|
||||
a: A, //~ ERROR unions cannot contain fields that may need dropping
|
||||
b: B
|
||||
|
|
|
@ -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,
|
||||
| ^^^^
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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() {}
|
|
@ -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`.
|
|
@ -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) };
|
||||
| ^^^^^
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) };
|
||||
| ^^^^^
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
union Foo {
|
||||
bar: i8,
|
||||
_blah: isize,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue