Auto merge of #60463 - mjbshaw:transparent, r=varkor,rkruppe
Implement RFC 2645 (transparent enums and unions) Tracking issue: #60405
This commit is contained in:
commit
8e948df707
34 changed files with 730 additions and 208 deletions
|
|
@ -0,0 +1,93 @@
|
|||
# `transparent_enums`
|
||||
|
||||
The tracking issue for this feature is [#60405]
|
||||
|
||||
[60405]: https://github.com/rust-lang/rust/issues/60405
|
||||
|
||||
----
|
||||
|
||||
The `transparent_enums` feature allows you mark `enum`s as
|
||||
`#[repr(transparent)]`. An `enum` may be `#[repr(transparent)]` if it has
|
||||
exactly one variant, and that variant matches the same conditions which `struct`
|
||||
requires for transparency. Some concrete illustrations follow.
|
||||
|
||||
```rust
|
||||
#![feature(transparent_enums)]
|
||||
|
||||
// This enum has the same representation as `f32`.
|
||||
#[repr(transparent)]
|
||||
enum SingleFieldEnum {
|
||||
Variant(f32)
|
||||
}
|
||||
|
||||
// This enum has the same representation as `usize`.
|
||||
#[repr(transparent)]
|
||||
enum MultiFieldEnum {
|
||||
Variant { field: usize, nothing: () },
|
||||
}
|
||||
```
|
||||
|
||||
For consistency with transparent `struct`s, `enum`s must have exactly one
|
||||
non-zero-sized field. If all fields are zero-sized, the `enum` must not be
|
||||
`#[repr(transparent)]`:
|
||||
|
||||
```rust
|
||||
#![feature(transparent_enums)]
|
||||
|
||||
// This (non-transparent) enum is already valid in stable Rust:
|
||||
pub enum GoodEnum {
|
||||
Nothing,
|
||||
}
|
||||
|
||||
// Error: transparent enum needs exactly one non-zero-sized field, but has 0
|
||||
// #[repr(transparent)]
|
||||
// pub enum BadEnum {
|
||||
// Nothing(()),
|
||||
// }
|
||||
|
||||
// Error: transparent enum needs exactly one non-zero-sized field, but has 0
|
||||
// #[repr(transparent)]
|
||||
// pub enum BadEmptyEnum {
|
||||
// Nothing,
|
||||
// }
|
||||
```
|
||||
|
||||
The one exception is if the `enum` is generic over `T` and has a field of type
|
||||
`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:
|
||||
|
||||
```rust
|
||||
#![feature(transparent_enums)]
|
||||
|
||||
// This enum has the same representation as `T`.
|
||||
#[repr(transparent)]
|
||||
pub enum GenericEnum<T> {
|
||||
Variant(T, ()),
|
||||
}
|
||||
|
||||
// This is okay even though `()` is a zero-sized type.
|
||||
pub const THIS_IS_OKAY: GenericEnum<()> = GenericEnum::Variant((), ());
|
||||
```
|
||||
|
||||
Transparent `enum`s require exactly one variant:
|
||||
|
||||
```rust
|
||||
// Error: transparent enum needs exactly one variant, but has 0
|
||||
// #[repr(transparent)]
|
||||
// pub enum TooFewVariants {
|
||||
// }
|
||||
|
||||
// Error: transparent enum needs exactly one variant, but has 2
|
||||
// #[repr(transparent)]
|
||||
// pub enum TooManyVariants {
|
||||
// First(usize),
|
||||
// Second,
|
||||
// }
|
||||
```
|
||||
|
||||
Like transarent `struct`s, a transparent `enum` of type `E` has the same layout,
|
||||
size, and ABI as its single non-ZST field. If it is generic over a type `T`, and
|
||||
all its fields are ZSTs except for exactly one field of type `T`, then it has
|
||||
the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
|
||||
|
||||
Like transparent `struct`s, transparent `enum`s are FFI-safe if and only if
|
||||
their underlying representation type is also FFI-safe.
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# `transparent_unions`
|
||||
|
||||
The tracking issue for this feature is [#60405]
|
||||
|
||||
[60405]: https://github.com/rust-lang/rust/issues/60405
|
||||
|
||||
----
|
||||
|
||||
The `transparent_unions` feature allows you mark `union`s as
|
||||
`#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
|
||||
same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
|
||||
this means the `union` must have exactly one non-zero-sized field). Some
|
||||
concrete illustrations follow.
|
||||
|
||||
```rust
|
||||
#![feature(transparent_unions)]
|
||||
|
||||
// This union has the same representation as `f32`.
|
||||
#[repr(transparent)]
|
||||
union SingleFieldUnion {
|
||||
field: f32,
|
||||
}
|
||||
|
||||
// This union has the same representation as `usize`.
|
||||
#[repr(transparent)]
|
||||
union MultiFieldUnion {
|
||||
field: usize,
|
||||
nothing: (),
|
||||
}
|
||||
```
|
||||
|
||||
For consistency with transparent `struct`s, `union`s must have exactly one
|
||||
non-zero-sized field. If all fields are zero-sized, the `union` must not be
|
||||
`#[repr(transparent)]`:
|
||||
|
||||
```rust
|
||||
#![feature(transparent_unions)]
|
||||
|
||||
// This (non-transparent) union is already valid in stable Rust:
|
||||
pub union GoodUnion {
|
||||
pub nothing: (),
|
||||
}
|
||||
|
||||
// Error: transparent union needs exactly one non-zero-sized field, but has 0
|
||||
// #[repr(transparent)]
|
||||
// pub union BadUnion {
|
||||
// pub nothing: (),
|
||||
// }
|
||||
```
|
||||
|
||||
The one exception is if the `union` is generic over `T` and has a field of type
|
||||
`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:
|
||||
|
||||
```rust
|
||||
#![feature(transparent_unions)]
|
||||
|
||||
// This union has the same representation as `T`.
|
||||
#[repr(transparent)]
|
||||
pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
|
||||
pub field: T,
|
||||
pub nothing: (),
|
||||
}
|
||||
|
||||
// This is okay even though `()` is a zero-sized type.
|
||||
pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
|
||||
```
|
||||
|
||||
Like transarent `struct`s, a transparent `union` of type `U` has the same
|
||||
layout, size, and ABI as its single non-ZST field. If it is generic over a type
|
||||
`T`, and all its fields are ZSTs except for exactly one field of type `T`, then
|
||||
it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
|
||||
|
||||
Like transparent `struct`s, transparent `union`s are FFI-safe if and only if
|
||||
their underlying representation type is also FFI-safe.
|
||||
|
||||
A `union` may not be eligible for the same nonnull-style optimizations that a
|
||||
`struct` or `enum` (with the same fields) are eligible for. Adding
|
||||
`#[repr(transparent)]` to `union` does not change this. To give a more concrete
|
||||
example, it is unspecified whether `size_of::<T>()` is equal to
|
||||
`size_of::<Option<T>>()`, where `T` is a `union` (regardless of whether or not
|
||||
it is transparent). The Rust compiler is free to perform this optimization if
|
||||
possible, but is not required to, and different compiler versions may differ in
|
||||
their application of these optimizations.
|
||||
|
|
@ -181,12 +181,9 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||
let (article, allowed_targets) = match hint.name_or_empty() {
|
||||
name @ sym::C | name @ sym::align => {
|
||||
is_c |= name == sym::C;
|
||||
if target != Target::Struct &&
|
||||
target != Target::Union &&
|
||||
target != Target::Enum {
|
||||
("a", "struct, enum or union")
|
||||
} else {
|
||||
continue
|
||||
match target {
|
||||
Target::Struct | Target::Union | Target::Enum => continue,
|
||||
_ => ("a", "struct, enum, or union"),
|
||||
}
|
||||
}
|
||||
sym::packed => {
|
||||
|
|
@ -207,10 +204,9 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||
}
|
||||
sym::transparent => {
|
||||
is_transparent = true;
|
||||
if target != Target::Struct {
|
||||
("a", "struct")
|
||||
} else {
|
||||
continue
|
||||
match target {
|
||||
Target::Struct | Target::Union | Target::Enum => continue,
|
||||
_ => ("a", "struct, enum, or union"),
|
||||
}
|
||||
}
|
||||
sym::i8 | sym::u8 | sym::i16 | sym::u16 |
|
||||
|
|
@ -241,7 +237,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||
if is_transparent && hints.len() > 1 {
|
||||
let hint_spans: Vec<_> = hint_spans.clone().collect();
|
||||
span_err!(self.tcx.sess, hint_spans, E0692,
|
||||
"transparent struct cannot have other repr hints");
|
||||
"transparent {} cannot have other repr hints", target);
|
||||
}
|
||||
// Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8)
|
||||
if (int_reprs > 1)
|
||||
|
|
@ -277,7 +273,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||
attr.span,
|
||||
stmt.span,
|
||||
"attribute should not be applied to a statement",
|
||||
"not a struct, enum or union",
|
||||
"not a struct, enum, or union",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -298,7 +294,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
|||
attr.span,
|
||||
expr.span,
|
||||
"attribute should not be applied to an expression",
|
||||
"not defining a struct, enum or union",
|
||||
"not defining a struct, enum, or union",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2303,7 +2303,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
|||
/// Returns an iterator over all fields contained
|
||||
/// by this ADT.
|
||||
#[inline]
|
||||
pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> {
|
||||
pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> + Clone {
|
||||
self.variants.iter().flat_map(|v| v.fields.iter())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -531,8 +531,8 @@ fn ty_is_known_nonnull<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> b
|
|||
match ty.sty {
|
||||
ty::FnPtr(_) => true,
|
||||
ty::Ref(..) => true,
|
||||
ty::Adt(field_def, substs) if field_def.repr.transparent() && field_def.is_struct() => {
|
||||
for field in &field_def.non_enum_variant().fields {
|
||||
ty::Adt(field_def, substs) if field_def.repr.transparent() && !field_def.is_union() => {
|
||||
for field in field_def.all_fields() {
|
||||
let field_ty = tcx.normalize_erasing_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
field.ty(tcx, substs),
|
||||
|
|
@ -627,8 +627,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
return FfiUnsafe {
|
||||
ty: ty,
|
||||
reason: "this struct has unspecified layout",
|
||||
help: Some("consider adding a #[repr(C)] or #[repr(transparent)] \
|
||||
attribute to this struct"),
|
||||
help: Some("consider adding a `#[repr(C)]` or \
|
||||
`#[repr(transparent)]` attribute to this struct"),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -668,11 +668,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
|
||||
}
|
||||
AdtKind::Union => {
|
||||
if !def.repr.c() {
|
||||
if !def.repr.c() && !def.repr.transparent() {
|
||||
return FfiUnsafe {
|
||||
ty: ty,
|
||||
reason: "this union has unspecified layout",
|
||||
help: Some("consider adding a #[repr(C)] attribute to this union"),
|
||||
help: Some("consider adding a `#[repr(C)]` or \
|
||||
`#[repr(transparent)]` attribute to this union"),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -690,6 +691,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
ParamEnv::reveal_all(),
|
||||
field.ty(cx, substs),
|
||||
);
|
||||
// repr(transparent) types are allowed to have arbitrary ZSTs, not just
|
||||
// PhantomData -- skip checking all ZST fields.
|
||||
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
|
||||
continue;
|
||||
}
|
||||
let r = self.check_type_for_ffi(cache, field_ty);
|
||||
match r {
|
||||
FfiSafe => {
|
||||
|
|
@ -712,14 +718,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
|
||||
// Check for a repr() attribute to specify the size of the
|
||||
// discriminant.
|
||||
if !def.repr.c() && def.repr.int.is_none() {
|
||||
if !def.repr.c() && !def.repr.transparent() && def.repr.int.is_none() {
|
||||
// Special-case types like `Option<extern fn()>`.
|
||||
if !is_repr_nullable_ptr(cx, ty, def, substs) {
|
||||
return FfiUnsafe {
|
||||
ty: ty,
|
||||
reason: "enum has no representation hint",
|
||||
help: Some("consider adding a #[repr(...)] attribute \
|
||||
to this enum"),
|
||||
help: Some("consider adding a `#[repr(C)]`, \
|
||||
`#[repr(transparent)]`, or integer `#[repr(...)]` \
|
||||
attribute to this enum"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -727,11 +734,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
// Check the contained variants.
|
||||
for variant in &def.variants {
|
||||
for field in &variant.fields {
|
||||
let arg = cx.normalize_erasing_regions(
|
||||
let field_ty = cx.normalize_erasing_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
field.ty(cx, substs),
|
||||
);
|
||||
let r = self.check_type_for_ffi(cache, arg);
|
||||
// repr(transparent) types are allowed to have arbitrary ZSTs, not
|
||||
// just PhantomData -- skip checking all ZST fields.
|
||||
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
|
||||
continue;
|
||||
}
|
||||
let r = self.check_type_for_ffi(cache, field_ty);
|
||||
match r {
|
||||
FfiSafe => {}
|
||||
FfiUnsafe { .. } => {
|
||||
|
|
|
|||
|
|
@ -1310,7 +1310,7 @@ fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let def = tcx.adt_def(def_id);
|
||||
def.destructor(tcx); // force the destructor to be evaluated
|
||||
check_representable(tcx, span, def_id);
|
||||
|
||||
check_transparent(tcx, span, def_id);
|
||||
check_packed(tcx, span, def_id);
|
||||
}
|
||||
|
||||
|
|
@ -1807,8 +1807,43 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
|
|||
return;
|
||||
}
|
||||
|
||||
if adt.is_enum() {
|
||||
if !tcx.features().transparent_enums {
|
||||
emit_feature_err(&tcx.sess.parse_sess,
|
||||
sym::transparent_enums,
|
||||
sp,
|
||||
GateIssue::Language,
|
||||
"transparent enums are unstable");
|
||||
}
|
||||
if adt.variants.len() != 1 {
|
||||
let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
|
||||
tcx.hir().span_if_local(variant.def_id).unwrap()
|
||||
}).collect();
|
||||
let mut err = struct_span_err!(tcx.sess, sp, E0731,
|
||||
"transparent enum needs exactly one variant, but has {}",
|
||||
adt.variants.len());
|
||||
if !variant_spans.is_empty() {
|
||||
err.span_note(variant_spans, &format!("the following variants exist on `{}`",
|
||||
tcx.def_path_str(def_id)));
|
||||
}
|
||||
err.emit();
|
||||
if adt.variants.is_empty() {
|
||||
// Don't bother checking the fields. No variants (and thus no fields) exist.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if adt.is_union() && !tcx.features().transparent_unions {
|
||||
emit_feature_err(&tcx.sess.parse_sess,
|
||||
sym::transparent_unions,
|
||||
sp,
|
||||
GateIssue::Language,
|
||||
"transparent unions are unstable");
|
||||
}
|
||||
|
||||
// For each field, figure out if it's known to be a ZST and align(1)
|
||||
let field_infos = adt.non_enum_variant().fields.iter().map(|field| {
|
||||
let field_infos = adt.all_fields().map(|field| {
|
||||
let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
|
||||
let param_env = tcx.param_env(field.did);
|
||||
let layout = tcx.layout_of(param_env.and(ty));
|
||||
|
|
@ -1823,16 +1858,24 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
|
|||
let non_zst_count = non_zst_fields.clone().count();
|
||||
if non_zst_count != 1 {
|
||||
let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
|
||||
struct_span_err!(tcx.sess, sp, E0690,
|
||||
"transparent struct needs exactly one non-zero-sized field, but has {}",
|
||||
non_zst_count)
|
||||
.span_note(field_spans, "non-zero-sized field")
|
||||
.emit();
|
||||
|
||||
let mut err = struct_span_err!(tcx.sess, sp, E0690,
|
||||
"{}transparent {} needs exactly one non-zero-sized field, but has {}",
|
||||
if adt.is_enum() { "the variant of a " } else { "" },
|
||||
adt.descr(),
|
||||
non_zst_count);
|
||||
if !field_spans.is_empty() {
|
||||
err.span_note(field_spans,
|
||||
&format!("the following non-zero-sized fields exist on `{}`:",
|
||||
tcx.def_path_str(def_id)));
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
for (span, zst, align1) in field_infos {
|
||||
if zst && !align1 {
|
||||
span_err!(tcx.sess, span, E0691,
|
||||
"zero-sized field in transparent struct has alignment larger than 1");
|
||||
"zero-sized field in transparent {} has alignment larger than 1",
|
||||
adt.descr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1899,6 +1942,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
|
||||
check_representable(tcx, sp, def_id);
|
||||
check_transparent(tcx, sp, def_id);
|
||||
}
|
||||
|
||||
fn report_unexpected_variant_res<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -4484,7 +4484,7 @@ let _ = (2.0 as f32).neg();
|
|||
|
||||
E0690: r##"
|
||||
A struct with the representation hint `repr(transparent)` had zero or more than
|
||||
on fields that were not guaranteed to be zero-sized.
|
||||
one fields that were not guaranteed to be zero-sized.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
|
|
@ -4519,8 +4519,8 @@ struct LengthWithUnit<U> {
|
|||
"##,
|
||||
|
||||
E0691: r##"
|
||||
A struct with the `repr(transparent)` representation hint contains a zero-sized
|
||||
field that requires non-trivial alignment.
|
||||
A struct, enum, or union with the `repr(transparent)` representation hint
|
||||
contains a zero-sized field that requires non-trivial alignment.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
|
|
@ -4535,11 +4535,11 @@ struct Wrapper(f32, ForceAlign32); // error: zero-sized field in transparent
|
|||
// struct has alignment larger than 1
|
||||
```
|
||||
|
||||
A transparent struct is supposed to be represented exactly like the piece of
|
||||
data it contains. Zero-sized fields with different alignment requirements
|
||||
potentially conflict with this property. In the example above, `Wrapper` would
|
||||
have to be aligned to 32 bytes even though `f32` has a smaller alignment
|
||||
requirement.
|
||||
A transparent struct, enum, or union is supposed to be represented exactly like
|
||||
the piece of data it contains. Zero-sized fields with different alignment
|
||||
requirements potentially conflict with this property. In the example above,
|
||||
`Wrapper` would have to be aligned to 32 bytes even though `f32` has a smaller
|
||||
alignment requirement.
|
||||
|
||||
Consider removing the over-aligned zero-sized field:
|
||||
|
||||
|
|
@ -4569,7 +4569,6 @@ the alignment of the zero-sized type is less than or equal to the data field's
|
|||
alignment.
|
||||
"##,
|
||||
|
||||
|
||||
E0699: r##"
|
||||
A method was called on a raw pointer whose inner type wasn't completely known.
|
||||
|
||||
|
|
@ -4680,6 +4679,26 @@ match r {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0731: r##"
|
||||
An enum with the representation hint `repr(transparent)` had zero or more than
|
||||
one variants.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0731
|
||||
#[repr(transparent)]
|
||||
enum Status { // error: transparent enum needs exactly one variant, but has 2
|
||||
Errno(u32),
|
||||
Ok,
|
||||
}
|
||||
```
|
||||
|
||||
Because transparent enums are represented exactly like one of their variants at
|
||||
run time, said variant must be uniquely determined. If there is no variant, or
|
||||
if there are multiple variants, it is not clear how the enum should be
|
||||
represented.
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
|
|
|
|||
|
|
@ -561,6 +561,12 @@ declare_features! (
|
|||
// FIXME Create issue
|
||||
(active, const_constructor, "1.37.0", Some(61456), None),
|
||||
|
||||
// #[repr(transparent)] on enums.
|
||||
(active, transparent_enums, "1.37.0", Some(60405), None),
|
||||
|
||||
// #[repr(transparent)] on unions.
|
||||
(active, transparent_unions, "1.37.0", Some(60405), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -623,6 +623,8 @@ symbols! {
|
|||
trait_alias,
|
||||
transmute,
|
||||
transparent,
|
||||
transparent_enums,
|
||||
transparent_unions,
|
||||
trivial_bounds,
|
||||
Try,
|
||||
try_blocks,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
// ignore-tidy-linelength
|
||||
|
||||
// ignore-arm
|
||||
// ignore-mips
|
||||
|
|
@ -7,36 +8,76 @@
|
|||
// ignore-powerpc64
|
||||
// See repr-transparent.rs
|
||||
|
||||
#![feature(transparent_enums, transparent_unions)]
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Big([u32; 16]);
|
||||
pub struct BigS([u32; 16]);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct BigW(Big);
|
||||
pub struct TsBigS(BigS);
|
||||
|
||||
// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], %Big* [[BIG_ARG_ATTRS:.*]])
|
||||
#[repr(transparent)]
|
||||
pub union TuBigS {
|
||||
field: BigS,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum TeBigS {
|
||||
Variant(BigS),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS:.*]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_Big(_: Big) -> Big { loop {} }
|
||||
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], %BigW* [[BIG_ARG_ATTRS]])
|
||||
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
|
||||
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub union BigU {
|
||||
foo: [u32; 16],
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct BigUw(BigU);
|
||||
pub struct TsBigU(BigU);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union TuBigU {
|
||||
field: BigU,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum TeBigU {
|
||||
Variant(BigU),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS:.*]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], %BigUw* [[BIGU_ARG_ATTRS]])
|
||||
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
|
||||
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
|
|
|
|||
|
|
@ -14,36 +14,76 @@
|
|||
// ignore-x86_64
|
||||
// See repr-transparent.rs
|
||||
|
||||
#![feature(transparent_enums, transparent_unions)]
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Big([u32; 16]);
|
||||
pub struct BigS([u32; 16]);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct BigW(Big);
|
||||
pub struct TsBigS(BigS);
|
||||
|
||||
// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [16 x i32]
|
||||
#[repr(transparent)]
|
||||
pub union TuBigS {
|
||||
field: BigS,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum TeBigS {
|
||||
Variant(BigS),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_Big(_: Big) -> Big { loop {} }
|
||||
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [16 x i32]
|
||||
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
|
||||
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub union BigU {
|
||||
foo: [u32; 16],
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct BigUw(BigU);
|
||||
pub struct TsBigU(BigU);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union TuBigU {
|
||||
field: BigU,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum TeBigU {
|
||||
Variant(BigU),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [16 x i32]
|
||||
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
|
||||
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
|
|
|
|||
|
|
@ -3,36 +3,76 @@
|
|||
// only-mips64
|
||||
// See repr-transparent.rs
|
||||
|
||||
#![feature(transparent_enums, transparent_unions)]
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Big([u32; 16]);
|
||||
pub struct BigS([u32; 16]);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct BigW(Big);
|
||||
pub struct TsBigS(BigS);
|
||||
|
||||
// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [8 x i64]
|
||||
#[repr(transparent)]
|
||||
pub union TuBigS {
|
||||
field: BigS,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum TeBigS {
|
||||
Variant(BigS),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_Big(_: Big) -> Big { loop {} }
|
||||
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [8 x i64]
|
||||
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
|
||||
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub union BigU {
|
||||
foo: [u32; 16],
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct BigUw(BigU);
|
||||
pub struct TsBigU(BigU);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union TuBigU {
|
||||
field: BigU,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum TeBigU {
|
||||
Variant(BigU),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [8 x i64]
|
||||
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
|
||||
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [8 x i64]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
|
||||
#![crate_type="lib"]
|
||||
#![feature(repr_simd)]
|
||||
#![feature(repr_simd, transparent_enums, transparent_unions)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Zst1;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Zst2(());
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct F32(f32);
|
||||
|
||||
|
|
@ -112,6 +115,44 @@ pub struct StructWithProjection(<f32 as Mirror>::It);
|
|||
#[no_mangle]
|
||||
pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum EnumF32 {
|
||||
Variant(F32)
|
||||
}
|
||||
|
||||
// CHECK: define float @test_EnumF32(float %arg0)
|
||||
#[no_mangle]
|
||||
pub extern fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum EnumF32WithZsts {
|
||||
Variant(Zst1, F32, Zst2)
|
||||
}
|
||||
|
||||
// CHECK: define float @test_EnumF32WithZsts(float %arg0)
|
||||
#[no_mangle]
|
||||
pub extern fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union UnionF32 {
|
||||
field: F32,
|
||||
}
|
||||
|
||||
// CHECK: define float @test_UnionF32(float %arg0)
|
||||
#[no_mangle]
|
||||
pub extern fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union UnionF32WithZsts {
|
||||
zst1: Zst1,
|
||||
field: F32,
|
||||
zst2: Zst2,
|
||||
}
|
||||
|
||||
// CHECK: define float @test_UnionF32WithZsts(float %arg0)
|
||||
#[no_mangle]
|
||||
pub extern fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
|
||||
|
||||
|
||||
// All that remains to be tested are aggregates. They are tested in separate files called repr-
|
||||
// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// run-pass
|
||||
#![feature(transparent_unions)]
|
||||
|
||||
use std::mem::size_of;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ptr::NonNull;
|
||||
|
|
@ -10,6 +12,11 @@ trait Mirror { type Image; }
|
|||
impl<T> Mirror for T { type Image = T; }
|
||||
struct ParamTypeStruct<T>(T);
|
||||
struct AssocTypeStruct<T>(<T as Mirror>::Image);
|
||||
#[repr(transparent)]
|
||||
union MaybeUninitUnion<T: Copy> {
|
||||
_value: T,
|
||||
_uninit: (),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Functions
|
||||
|
|
@ -29,9 +36,12 @@ fn main() {
|
|||
// Pointers - Box<T>
|
||||
assert_eq!(size_of::<Box<isize>>(), size_of::<Option<Box<isize>>>());
|
||||
|
||||
// The optimization can't apply to raw pointers
|
||||
// The optimization can't apply to raw pointers or unions with a ZST field.
|
||||
assert!(size_of::<Option<*const isize>>() != size_of::<*const isize>());
|
||||
assert!(Some(0 as *const isize).is_some()); // Can't collapse None to null
|
||||
assert_ne!(size_of::<fn(isize)>(), size_of::<Option<MaybeUninitUnion<fn(isize)>>>());
|
||||
assert_ne!(size_of::<&str>(), size_of::<Option<MaybeUninitUnion<&str>>>());
|
||||
assert_ne!(size_of::<NonNull<isize>>(), size_of::<Option<MaybeUninitUnion<NonNull<isize>>>>());
|
||||
|
||||
struct Foo {
|
||||
_a: Box<isize>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
|
||||
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum, or union
|
||||
fn f() {}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
error[E0517]: attribute should be applied to struct, enum or union
|
||||
error[E0517]: attribute should be applied to struct, enum, or union
|
||||
--> $DIR/attr-usage-repr.rs:3:8
|
||||
|
|
||||
LL | #[repr(C)]
|
||||
| ^
|
||||
LL | fn f() {}
|
||||
| --------- not a struct, enum or union
|
||||
| --------- not a struct, enum, or union
|
||||
|
||||
error[E0517]: attribute should be applied to enum
|
||||
--> $DIR/attr-usage-repr.rs:15:8
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
error[E0517]: attribute should be applied to struct, enum or union
|
||||
error[E0517]: attribute should be applied to struct, enum, or union
|
||||
--> $DIR/E0517.rs:1:8
|
||||
|
|
||||
LL | #[repr(C)]
|
||||
| ^
|
||||
LL | type Foo = u8;
|
||||
| -------------- not a struct, enum or union
|
||||
| -------------- not a struct, enum, or union
|
||||
|
||||
error[E0517]: attribute should be applied to struct or union
|
||||
--> $DIR/E0517.rs:4:8
|
||||
|
|
@ -22,14 +22,14 @@ LL | #[repr(u8)]
|
|||
LL | struct Foo3 {bar: bool, baz: bool}
|
||||
| ---------------------------------- not an enum
|
||||
|
||||
error[E0517]: attribute should be applied to struct, enum or union
|
||||
error[E0517]: attribute should be applied to struct, enum, or union
|
||||
--> $DIR/E0517.rs:10:8
|
||||
|
|
||||
LL | #[repr(C)]
|
||||
| ^
|
||||
LL | / impl Foo3 {
|
||||
LL | | }
|
||||
| |_- not a struct, enum or union
|
||||
| |_- not a struct, enum, or union
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
#[repr(transparent)]
|
||||
enum OkButUnstableEnum { //~ ERROR transparent enums are unstable
|
||||
Foo((), String, ()),
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
error[E0658]: transparent enums are unstable
|
||||
--> $DIR/feature-gate-transparent_enums.rs:2:1
|
||||
|
|
||||
LL | / enum OkButUnstableEnum {
|
||||
LL | | Foo((), String, ()),
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/60405
|
||||
= help: add #![feature(transparent_enums)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#[repr(transparent)]
|
||||
union OkButUnstableUnion { //~ ERROR transparent unions are unstable
|
||||
field: u8,
|
||||
zst: (),
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
error[E0658]: transparent unions are unstable
|
||||
--> $DIR/feature-gate-transparent_unions.rs:2:1
|
||||
|
|
||||
LL | / union OkButUnstableUnion {
|
||||
LL | | field: u8,
|
||||
LL | | zst: (),
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/60405
|
||||
= help: add #![feature(transparent_unions)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -9,7 +9,7 @@ note: lint level defined here
|
|||
|
|
||||
LL | #![deny(improper_ctypes)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/issue-14309.rs:4:1
|
||||
|
|
||||
|
|
@ -24,7 +24,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
|
|||
LL | fn bar(x: B);
|
||||
| ^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/issue-14309.rs:4:1
|
||||
|
|
||||
|
|
@ -39,7 +39,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
|
|||
LL | fn qux(x: A2);
|
||||
| ^^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/issue-14309.rs:4:1
|
||||
|
|
||||
|
|
@ -54,7 +54,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
|
|||
LL | fn quux(x: B2);
|
||||
| ^^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/issue-14309.rs:4:1
|
||||
|
|
||||
|
|
@ -69,7 +69,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
|
|||
LL | fn fred(x: D);
|
||||
| ^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/issue-14309.rs:4:1
|
||||
|
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ note: lint level defined here
|
|||
LL | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
= note: #[deny(improper_ctypes)] implied by #[deny(warnings)]
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/issue-16250.rs:3:1
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
fn main() {
|
||||
#[inline] struct Foo; //~ ERROR attribute should be applied to function or closure
|
||||
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum or union
|
||||
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum, or union
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ error[E0518]: attribute should be applied to function or closure
|
|||
LL | #[inline] struct Foo;
|
||||
| ^^^^^^^^^ ----------- not a function or closure
|
||||
|
||||
error[E0517]: attribute should be applied to struct, enum or union
|
||||
error[E0517]: attribute should be applied to struct, enum, or union
|
||||
--> $DIR/issue-31769.rs:3:12
|
||||
|
|
||||
LL | #[repr(C)] fn foo() {}
|
||||
| ^ ----------- not a struct, enum or union
|
||||
| ^ ----------- not a struct, enum, or union
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ error[E0517]: attribute should not be applied to a statement
|
|||
LL | #[repr(nothing)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | let _x = 0;
|
||||
| ----------- not a struct, enum or union
|
||||
| ----------- not a struct, enum, or union
|
||||
|
||||
error[E0517]: attribute should not be applied to an expression
|
||||
--> $DIR/issue-43988.rs:18:5
|
||||
|
|
@ -42,7 +42,7 @@ LL | #[repr(something_not_real)]
|
|||
LL | / loop {
|
||||
LL | | ()
|
||||
LL | | };
|
||||
| |_____- not defining a struct, enum or union
|
||||
| |_____- not defining a struct, enum, or union
|
||||
|
||||
error[E0517]: attribute should not be applied to a statement
|
||||
--> $DIR/issue-43988.rs:24:5
|
||||
|
|
@ -50,7 +50,7 @@ error[E0517]: attribute should not be applied to a statement
|
|||
LL | #[repr]
|
||||
| ^^^^^^^
|
||||
LL | let _y = "123";
|
||||
| --------------- not a struct, enum or union
|
||||
| --------------- not a struct, enum, or union
|
||||
|
||||
error[E0518]: attribute should be applied to function or closure
|
||||
--> $DIR/issue-43988.rs:31:5
|
||||
|
|
@ -64,7 +64,7 @@ error[E0517]: attribute should not be applied to an expression
|
|||
--> $DIR/issue-43988.rs:35:14
|
||||
|
|
||||
LL | let _z = #[repr] 1;
|
||||
| ^^^^^^^ - not defining a struct, enum or union
|
||||
| ^^^^^^^ - not defining a struct, enum, or union
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(transparent_enums, transparent_unions)]
|
||||
#![deny(improper_ctypes)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
|
@ -18,7 +19,17 @@ enum U8 { A, B, C }
|
|||
enum Isize { A, B, C }
|
||||
|
||||
#[repr(transparent)]
|
||||
struct Transparent<T>(T, std::marker::PhantomData<Z>);
|
||||
struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
|
||||
|
||||
#[repr(transparent)]
|
||||
enum TransparentEnum<T> {
|
||||
Variant(T, std::marker::PhantomData<Z>),
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
union TransparentUnion<T: Copy> {
|
||||
field: T,
|
||||
}
|
||||
|
||||
struct Rust<T>(T);
|
||||
|
||||
|
|
@ -47,7 +58,10 @@ extern {
|
|||
fn nonzero_i128(x: Option<num::NonZeroI128>);
|
||||
//~^ ERROR 128-bit integers don't currently have a known stable ABI
|
||||
fn nonzero_isize(x: Option<num::NonZeroIsize>);
|
||||
fn repr_transparent(x: Option<Transparent<num::NonZeroU8>>);
|
||||
fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
|
||||
fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
|
||||
fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
|
||||
//~^ ERROR enum has no representation hint
|
||||
fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR enum has no representation hint
|
||||
fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR enum has no representation hint
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,82 @@
|
|||
error: `extern` block uses type `U` which is not FFI-safe: enum has no representation hint
|
||||
--> $DIR/lint-ctypes-enum.rs:27:13
|
||||
--> $DIR/lint-ctypes-enum.rs:38:13
|
||||
|
|
||||
LL | fn uf(x: U);
|
||||
| ^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:1:9
|
||||
--> $DIR/lint-ctypes-enum.rs:2:9
|
||||
|
|
||||
LL | #![deny(improper_ctypes)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= help: consider adding a #[repr(...)] attribute to this enum
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
note: type defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:7:1
|
||||
--> $DIR/lint-ctypes-enum.rs:8:1
|
||||
|
|
||||
LL | enum U { A }
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `B` which is not FFI-safe: enum has no representation hint
|
||||
--> $DIR/lint-ctypes-enum.rs:28:13
|
||||
--> $DIR/lint-ctypes-enum.rs:39:13
|
||||
|
|
||||
LL | fn bf(x: B);
|
||||
| ^
|
||||
|
|
||||
= help: consider adding a #[repr(...)] attribute to this enum
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
note: type defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:8:1
|
||||
--> $DIR/lint-ctypes-enum.rs:9:1
|
||||
|
|
||||
LL | enum B { C, D }
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `T` which is not FFI-safe: enum has no representation hint
|
||||
--> $DIR/lint-ctypes-enum.rs:29:13
|
||||
--> $DIR/lint-ctypes-enum.rs:40:13
|
||||
|
|
||||
LL | fn tf(x: T);
|
||||
| ^
|
||||
|
|
||||
= help: consider adding a #[repr(...)] attribute to this enum
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
note: type defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:9:1
|
||||
--> $DIR/lint-ctypes-enum.rs:10:1
|
||||
|
|
||||
LL | enum T { E, F, G }
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
||||
--> $DIR/lint-ctypes-enum.rs:40:23
|
||||
--> $DIR/lint-ctypes-enum.rs:51:23
|
||||
|
|
||||
LL | fn nonzero_u128(x: Option<num::NonZeroU128>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
||||
--> $DIR/lint-ctypes-enum.rs:47:23
|
||||
--> $DIR/lint-ctypes-enum.rs:58:23
|
||||
|
|
||||
LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
|
||||
--> $DIR/lint-ctypes-enum.rs:63:28
|
||||
|
|
||||
LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
|
||||
error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
|
||||
--> $DIR/lint-ctypes-enum.rs:51:20
|
||||
--> $DIR/lint-ctypes-enum.rs:65:20
|
||||
|
|
||||
LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a #[repr(...)] attribute to this enum
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
|
||||
error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>` which is not FFI-safe: enum has no representation hint
|
||||
--> $DIR/lint-ctypes-enum.rs:52:20
|
||||
--> $DIR/lint-ctypes-enum.rs:66:20
|
||||
|
|
||||
LL | fn no_result(x: Result<(), num::NonZeroI32>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a #[repr(...)] attribute to this enum
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ note: lint level defined here
|
|||
|
|
||||
LL | #![deny(improper_ctypes)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/lint-ctypes.rs:24:1
|
||||
|
|
||||
|
|
@ -22,7 +22,7 @@ error: `extern` block uses type `Foo` which is not FFI-safe: this struct has uns
|
|||
LL | pub fn ptr_type2(size: *const Foo);
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
note: type defined here
|
||||
--> $DIR/lint-ctypes.rs:24:1
|
||||
|
|
||||
|
|
@ -51,7 +51,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
|
|||
LL | pub fn box_type(p: Box<u32>);
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
|
||||
error: `extern` block uses type `char` which is not FFI-safe: the `char` type has no C equivalent
|
||||
--> $DIR/lint-ctypes.rs:51:25
|
||||
|
|
@ -142,7 +142,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
|
|||
LL | pub fn fn_contained(p: RustBadRet);
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
|
||||
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
||||
--> $DIR/lint-ctypes.rs:64:32
|
||||
|
|
@ -164,7 +164,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
|
|||
LL | pub fn transparent_fn(p: TransparentBadFn);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
|
||||
error: aborting due to 20 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,5 @@
|
|||
// See also repr-transparent.rs
|
||||
|
||||
#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
|
||||
enum Void {} //~| ERROR should be applied to struct
|
||||
|
||||
#[repr(transparent)] //~ ERROR should be applied to struct
|
||||
enum FieldlessEnum {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[repr(transparent)] //~ ERROR should be applied to struct
|
||||
enum Enum {
|
||||
Foo(String),
|
||||
Bar(u32),
|
||||
}
|
||||
|
||||
#[repr(transparent)] //~ ERROR should be applied to struct
|
||||
union Foo {
|
||||
u: u32,
|
||||
s: i32
|
||||
}
|
||||
|
||||
#[repr(transparent)] //~ ERROR should be applied to struct
|
||||
fn cant_repr_this() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,69 +1,19 @@
|
|||
error[E0517]: attribute should be applied to struct
|
||||
error[E0517]: attribute should be applied to struct, enum, or union
|
||||
--> $DIR/repr-transparent-other-items.rs:3:8
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^
|
||||
LL | enum Void {}
|
||||
| ------------ not a struct
|
||||
|
||||
error[E0517]: attribute should be applied to struct
|
||||
--> $DIR/repr-transparent-other-items.rs:6:8
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^
|
||||
LL | / enum FieldlessEnum {
|
||||
LL | | Foo,
|
||||
LL | | Bar,
|
||||
LL | | }
|
||||
| |_- not a struct
|
||||
|
||||
error[E0517]: attribute should be applied to struct
|
||||
--> $DIR/repr-transparent-other-items.rs:12:8
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^
|
||||
LL | / enum Enum {
|
||||
LL | | Foo(String),
|
||||
LL | | Bar(u32),
|
||||
LL | | }
|
||||
| |_- not a struct
|
||||
|
||||
error[E0517]: attribute should be applied to struct
|
||||
--> $DIR/repr-transparent-other-items.rs:18:8
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^
|
||||
LL | / union Foo {
|
||||
LL | | u: u32,
|
||||
LL | | s: i32
|
||||
LL | | }
|
||||
| |_- not a struct
|
||||
|
||||
error[E0517]: attribute should be applied to struct
|
||||
--> $DIR/repr-transparent-other-items.rs:24:8
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^
|
||||
LL | fn cant_repr_this() {}
|
||||
| ---------------------- not a struct
|
||||
| ---------------------- not a struct, enum, or union
|
||||
|
||||
error[E0517]: attribute should be applied to struct
|
||||
--> $DIR/repr-transparent-other-items.rs:27:8
|
||||
error[E0517]: attribute should be applied to struct, enum, or union
|
||||
--> $DIR/repr-transparent-other-items.rs:6:8
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^
|
||||
LL | static CANT_REPR_THIS: u32 = 0;
|
||||
| ------------------------------- not a struct
|
||||
| ------------------------------- not a struct, enum, or union
|
||||
|
||||
error[E0084]: unsupported representation for zero-variant enum
|
||||
--> $DIR/repr-transparent-other-items.rs:3:1
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
LL | enum Void {}
|
||||
| ------------ zero-variant enum
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0084, E0517.
|
||||
For more information about an error, try `rustc --explain E0084`.
|
||||
For more information about this error, try `rustc --explain E0517`.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// - repr-transparent-other-reprs.rs
|
||||
// - repr-transparent-other-items.rs
|
||||
|
||||
#![feature(repr_align)]
|
||||
#![feature(repr_align, transparent_enums, transparent_unions)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
|
@ -39,4 +39,36 @@ struct ZstAlign32<T>(PhantomData<T>);
|
|||
#[repr(transparent)]
|
||||
struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1
|
||||
|
||||
#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
|
||||
enum Void {}
|
||||
//~^ ERROR transparent enum needs exactly one variant, but has 0
|
||||
|
||||
#[repr(transparent)]
|
||||
enum FieldlessEnum { //~ ERROR transparent enum needs exactly one non-zero-sized field, but has 0
|
||||
Foo,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
enum TooManyFieldsEnum {
|
||||
Foo(u32, String),
|
||||
}
|
||||
//~^^^ ERROR transparent enum needs exactly one non-zero-sized field, but has 2
|
||||
|
||||
#[repr(transparent)]
|
||||
enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
|
||||
Foo(String),
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0
|
||||
u: (),
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
union TooManyFields { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 2
|
||||
u: u32,
|
||||
s: i32
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -3,32 +3,24 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
|
|||
|
|
||||
LL | struct NoFields;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: non-zero-sized field
|
||||
|
||||
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
|
||||
--> $DIR/repr-transparent.rs:14:1
|
||||
|
|
||||
LL | struct ContainsOnlyZst(());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: non-zero-sized field
|
||||
|
||||
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
|
||||
--> $DIR/repr-transparent.rs:17:1
|
||||
|
|
||||
LL | struct ContainsOnlyZstArray([bool; 0]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: non-zero-sized field
|
||||
|
||||
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
|
||||
--> $DIR/repr-transparent.rs:20:1
|
||||
|
|
||||
LL | struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: non-zero-sized field
|
||||
|
||||
error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
|
||||
--> $DIR/repr-transparent.rs:24:1
|
||||
|
|
@ -36,7 +28,7 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
|
|||
LL | struct MultipleNonZst(u8, u8);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: non-zero-sized field
|
||||
note: the following non-zero-sized fields exist on `MultipleNonZst`:
|
||||
--> $DIR/repr-transparent.rs:24:23
|
||||
|
|
||||
LL | struct MultipleNonZst(u8, u8);
|
||||
|
|
@ -48,7 +40,7 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
|
|||
LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: non-zero-sized field
|
||||
note: the following non-zero-sized fields exist on `StructWithProjection`:
|
||||
--> $DIR/repr-transparent.rs:30:33
|
||||
|
|
||||
LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
|
||||
|
|
@ -66,7 +58,85 @@ error[E0691]: zero-sized field in transparent struct has alignment larger than 1
|
|||
LL | struct GenericAlign<T>(ZstAlign32<T>, u32);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0084]: unsupported representation for zero-variant enum
|
||||
--> $DIR/repr-transparent.rs:42:1
|
||||
|
|
||||
LL | #[repr(transparent)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
LL | enum Void {}
|
||||
| ------------ zero-variant enum
|
||||
|
||||
Some errors have detailed explanations: E0690, E0691.
|
||||
For more information about an error, try `rustc --explain E0690`.
|
||||
error[E0731]: transparent enum needs exactly one variant, but has 0
|
||||
--> $DIR/repr-transparent.rs:43:1
|
||||
|
|
||||
LL | enum Void {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 0
|
||||
--> $DIR/repr-transparent.rs:47:1
|
||||
|
|
||||
LL | / enum FieldlessEnum {
|
||||
LL | | Foo,
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 2
|
||||
--> $DIR/repr-transparent.rs:52:1
|
||||
|
|
||||
LL | / enum TooManyFieldsEnum {
|
||||
LL | | Foo(u32, String),
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
note: the following non-zero-sized fields exist on `TooManyFieldsEnum`:
|
||||
--> $DIR/repr-transparent.rs:53:9
|
||||
|
|
||||
LL | Foo(u32, String),
|
||||
| ^^^ ^^^^^^
|
||||
|
||||
error[E0731]: transparent enum needs exactly one variant, but has 2
|
||||
--> $DIR/repr-transparent.rs:58:1
|
||||
|
|
||||
LL | / enum TooManyVariants {
|
||||
LL | | Foo(String),
|
||||
LL | | Bar,
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
note: the following variants exist on `TooManyVariants`
|
||||
--> $DIR/repr-transparent.rs:59:5
|
||||
|
|
||||
LL | Foo(String),
|
||||
| ^^^^^^^^^^^
|
||||
LL | Bar,
|
||||
| ^^^
|
||||
|
||||
error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0
|
||||
--> $DIR/repr-transparent.rs:64:1
|
||||
|
|
||||
LL | / union UnitUnion {
|
||||
LL | | u: (),
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2
|
||||
--> $DIR/repr-transparent.rs:69:1
|
||||
|
|
||||
LL | / union TooManyFields {
|
||||
LL | | u: u32,
|
||||
LL | | s: i32
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
note: the following non-zero-sized fields exist on `TooManyFields`:
|
||||
--> $DIR/repr-transparent.rs:70:5
|
||||
|
|
||||
LL | u: u32,
|
||||
| ^^^^^^
|
||||
LL | s: i32
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0084, E0690, E0691, E0731.
|
||||
For more information about an error, try `rustc --explain E0084`.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ note: lint level defined here
|
|||
|
|
||||
LL | #![deny(improper_ctypes)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= help: consider adding a #[repr(C)] attribute to this union
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
|
||||
note: type defined here
|
||||
--> $DIR/union-repr-c.rs:9:1
|
||||
|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue