Check representation of unnamed fields
This commit is contained in:
parent
7d012e8f19
commit
7660d6bf2c
@ -439,6 +439,17 @@ hir_analysis_typeof_reserved_keyword_used =
|
|||||||
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
|
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
|
||||||
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
|
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
|
||||||
|
|
||||||
|
hir_analysis_unnamed_fields_repr_field_defined = unnamed field defined here
|
||||||
|
|
||||||
|
hir_analysis_unnamed_fields_repr_field_missing_repr_c =
|
||||||
|
named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
.label = unnamed field defined here
|
||||||
|
.field_ty_label = `{$field_ty}` defined here
|
||||||
|
|
||||||
|
hir_analysis_unnamed_fields_repr_missing_repr_c =
|
||||||
|
{$adt_kind} with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
.label = {$adt_kind} `{$adt_name}` defined here
|
||||||
|
|
||||||
hir_analysis_unrecognized_atomic_operation =
|
hir_analysis_unrecognized_atomic_operation =
|
||||||
unrecognized atomic operation function: `{$op}`
|
unrecognized atomic operation function: `{$op}`
|
||||||
.label = unrecognized atomic operation
|
.label = unrecognized atomic operation
|
||||||
|
@ -80,6 +80,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
|
|
||||||
check_transparent(tcx, def);
|
check_transparent(tcx, def);
|
||||||
check_packed(tcx, span, def);
|
check_packed(tcx, span, def);
|
||||||
|
check_unnamed_fields(tcx, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
@ -89,6 +90,54 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
check_transparent(tcx, def);
|
check_transparent(tcx, def);
|
||||||
check_union_fields(tcx, span, def_id);
|
check_union_fields(tcx, span, def_id);
|
||||||
check_packed(tcx, span, def);
|
check_packed(tcx, span, def);
|
||||||
|
check_unnamed_fields(tcx, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check the representation of adts with unnamed fields.
|
||||||
|
fn check_unnamed_fields(tcx: TyCtxt<'_>, def: ty::AdtDef<'_>) {
|
||||||
|
if def.is_enum() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let variant = def.non_enum_variant();
|
||||||
|
if !variant.has_unnamed_fields() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if !def.is_anonymous() {
|
||||||
|
let adt_kind = def.descr();
|
||||||
|
let span = tcx.def_span(def.did());
|
||||||
|
let unnamed_fields = variant
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.filter(|f| f.is_unnamed())
|
||||||
|
.map(|f| {
|
||||||
|
let span = tcx.def_span(f.did);
|
||||||
|
errors::UnnamedFieldsReprFieldDefined { span }
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
debug_assert_ne!(unnamed_fields.len(), 0, "expect unnamed fields in this adt");
|
||||||
|
let adt_name = tcx.item_name(def.did());
|
||||||
|
if !def.repr().c() {
|
||||||
|
tcx.dcx().emit_err(errors::UnnamedFieldsRepr::MissingReprC {
|
||||||
|
span,
|
||||||
|
adt_kind,
|
||||||
|
adt_name,
|
||||||
|
unnamed_fields,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for field in variant.fields.iter().filter(|f| f.is_unnamed()) {
|
||||||
|
let field_ty = tcx.type_of(field.did).instantiate_identity();
|
||||||
|
if let Some(adt) = field_ty.ty_adt_def()
|
||||||
|
&& !adt.is_anonymous()
|
||||||
|
&& !adt.repr().c()
|
||||||
|
{
|
||||||
|
tcx.dcx().emit_err(errors::UnnamedFieldsRepr::FieldMissingReprC {
|
||||||
|
span: tcx.def_span(field.did),
|
||||||
|
field_ty_span: tcx.def_span(adt.did()),
|
||||||
|
field_ty,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that the fields of the `union` do not need dropping.
|
/// Check that the fields of the `union` do not need dropping.
|
||||||
|
@ -997,7 +997,11 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let is_anonymous = item.ident.name == kw::Empty;
|
let is_anonymous = item.ident.name == kw::Empty;
|
||||||
let repr = tcx.repr_options_of_def(def_id.to_def_id());
|
let repr = if is_anonymous {
|
||||||
|
tcx.adt_def(tcx.local_parent(def_id)).repr()
|
||||||
|
} else {
|
||||||
|
tcx.repr_options_of_def(def_id.to_def_id())
|
||||||
|
};
|
||||||
let (kind, variants) = match &item.kind {
|
let (kind, variants) = match &item.kind {
|
||||||
ItemKind::Enum(def, _) => {
|
ItemKind::Enum(def, _) => {
|
||||||
let mut distance_from_explicit = 0;
|
let mut distance_from_explicit = 0;
|
||||||
|
@ -1571,3 +1571,33 @@ pub(crate) enum UnusedGenericParameterHelp {
|
|||||||
#[help(hir_analysis_unused_generic_parameter_ty_alias_help)]
|
#[help(hir_analysis_unused_generic_parameter_ty_alias_help)]
|
||||||
TyAlias { param_name: Ident },
|
TyAlias { param_name: Ident },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
pub enum UnnamedFieldsRepr<'a> {
|
||||||
|
#[diag(hir_analysis_unnamed_fields_repr_missing_repr_c)]
|
||||||
|
MissingReprC {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
span: Span,
|
||||||
|
adt_kind: &'static str,
|
||||||
|
adt_name: Symbol,
|
||||||
|
#[subdiagnostic]
|
||||||
|
unnamed_fields: Vec<UnnamedFieldsReprFieldDefined>,
|
||||||
|
},
|
||||||
|
#[diag(hir_analysis_unnamed_fields_repr_field_missing_repr_c)]
|
||||||
|
FieldMissingReprC {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
span: Span,
|
||||||
|
#[label(hir_analysis_field_ty_label)]
|
||||||
|
field_ty_span: Span,
|
||||||
|
field_ty: Ty<'a>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[note(hir_analysis_unnamed_fields_repr_field_defined)]
|
||||||
|
pub struct UnnamedFieldsReprFieldDefined {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
@ -80,6 +80,22 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
|
|||||||
let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
|
let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
|
||||||
let def = self.create_def(field.id, name, DefKind::Field, field.span);
|
let def = self.create_def(field.id, name, DefKind::Field, field.span);
|
||||||
self.with_parent(def, |this| visit::walk_field_def(this, field));
|
self.with_parent(def, |this| visit::walk_field_def(this, field));
|
||||||
|
self.visit_anon_adt(&field.ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_anon_adt(&mut self, ty: &'a Ty) {
|
||||||
|
let def_kind = match &ty.kind {
|
||||||
|
TyKind::AnonStruct(..) => DefKind::Struct,
|
||||||
|
TyKind::AnonUnion(..) => DefKind::Union,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
match &ty.kind {
|
||||||
|
TyKind::AnonStruct(node_id, _) | TyKind::AnonUnion(node_id, _) => {
|
||||||
|
let def_id = self.create_def(*node_id, kw::Empty, def_kind, ty.span);
|
||||||
|
self.with_parent(def_id, |this| visit::walk_ty(this, ty));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,19 +342,8 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||||
match &ty.kind {
|
match &ty.kind {
|
||||||
TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
|
TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
|
||||||
TyKind::AnonStruct(node_id, fields) | TyKind::AnonUnion(node_id, fields) => {
|
// Anonymous structs or unions are visited later after defined.
|
||||||
let def_kind = match &ty.kind {
|
TyKind::AnonStruct(..) | TyKind::AnonUnion(..) => {}
|
||||||
TyKind::AnonStruct(..) => DefKind::Struct,
|
|
||||||
TyKind::AnonUnion(..) => DefKind::Union,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
let def_id = self.create_def(*node_id, kw::Empty, def_kind, ty.span);
|
|
||||||
self.with_parent(def_id, |this| {
|
|
||||||
for f in fields {
|
|
||||||
this.visit_field_def(f);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => visit::walk_ty(self, ty),
|
_ => visit::walk_ty(self, ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2216,11 +2216,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||||||
// if all of its fields are `Copy` and `Clone`
|
// if all of its fields are `Copy` and `Clone`
|
||||||
ty::Adt(adt, args) if adt.is_anonymous() => {
|
ty::Adt(adt, args) if adt.is_anonymous() => {
|
||||||
// (*) binder moved here
|
// (*) binder moved here
|
||||||
Where(
|
Where(obligation.predicate.rebind(
|
||||||
obligation
|
adt.non_enum_variant().fields.iter().map(|f| f.ty(self.tcx(), args)).collect(),
|
||||||
.predicate
|
))
|
||||||
.rebind(adt.non_enum_variant().fields.iter().map(|f| f.ty(self.tcx(), args)).collect()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {
|
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {
|
||||||
|
@ -26,7 +26,7 @@ fn bar(_1: Bar) -> () {
|
|||||||
StorageDead(_2);
|
StorageDead(_2);
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
StorageLive(_5);
|
StorageLive(_5);
|
||||||
_5 = ((_1.1: Bar::_::{anon_adt#0}).0: i8);
|
_5 = ((_1.1: Bar::{anon_adt#0}).0: i8);
|
||||||
_4 = access::<i8>(move _5) -> [return: bb2, unwind: bb5];
|
_4 = access::<i8>(move _5) -> [return: bb2, unwind: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ fn bar(_1: Bar) -> () {
|
|||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
_7 = ((_1.1: Bar::_::{anon_adt#0}).1: bool);
|
_7 = ((_1.1: Bar::{anon_adt#0}).1: bool);
|
||||||
_6 = access::<bool>(move _7) -> [return: bb3, unwind: bb5];
|
_6 = access::<bool>(move _7) -> [return: bb3, unwind: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ fn bar(_1: Bar) -> () {
|
|||||||
StorageDead(_6);
|
StorageDead(_6);
|
||||||
StorageLive(_8);
|
StorageLive(_8);
|
||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
_9 = (((_1.2: Bar::_::{anon_adt#0}).0: Bar::_::{anon_adt#0}::_::{anon_adt#0}).0: [u8; 1]);
|
_9 = (((_1.2: Bar::{anon_adt#1}).0: Bar::{anon_adt#1}::{anon_adt#0}).0: [u8; 1]);
|
||||||
_8 = access::<[u8; 1]>(move _9) -> [return: bb4, unwind: bb5];
|
_8 = access::<[u8; 1]>(move _9) -> [return: bb4, unwind: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ fn foo(_1: Foo) -> () {
|
|||||||
StorageDead(_2);
|
StorageDead(_2);
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
StorageLive(_5);
|
StorageLive(_5);
|
||||||
_5 = ((_1.1: Foo::_::{anon_adt#0}).0: i8);
|
_5 = ((_1.1: Foo::{anon_adt#0}).0: i8);
|
||||||
_4 = access::<i8>(move _5) -> [return: bb2, unwind: bb5];
|
_4 = access::<i8>(move _5) -> [return: bb2, unwind: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ fn foo(_1: Foo) -> () {
|
|||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
_7 = ((_1.1: Foo::_::{anon_adt#0}).1: bool);
|
_7 = ((_1.1: Foo::{anon_adt#0}).1: bool);
|
||||||
_6 = access::<bool>(move _7) -> [return: bb3, unwind: bb5];
|
_6 = access::<bool>(move _7) -> [return: bb3, unwind: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ fn foo(_1: Foo) -> () {
|
|||||||
StorageDead(_6);
|
StorageDead(_6);
|
||||||
StorageLive(_8);
|
StorageLive(_8);
|
||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
_9 = (((_1.2: Foo::_::{anon_adt#0}).0: Foo::_::{anon_adt#0}::_::{anon_adt#0}).0: [u8; 1]);
|
_9 = (((_1.2: Foo::{anon_adt#1}).0: Foo::{anon_adt#1}::{anon_adt#0}).0: [u8; 1]);
|
||||||
_8 = access::<[u8; 1]>(move _9) -> [return: bb4, unwind: bb5];
|
_8 = access::<[u8; 1]>(move _9) -> [return: bb4, unwind: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#[repr(C)]
|
||||||
struct Foo {
|
struct Foo {
|
||||||
foo: u8,
|
foo: u8,
|
||||||
_: union { //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
_: union { //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||||
@ -7,6 +8,7 @@ struct Foo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
union Bar {
|
union Bar {
|
||||||
foobar: u8,
|
foobar: u8,
|
||||||
_: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
_: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||||
@ -16,7 +18,10 @@ union Bar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
struct Baz {
|
struct Baz {
|
||||||
_: S //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
_: S //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0658]: unnamed fields are not yet fully implemented
|
error[E0658]: unnamed fields are not yet fully implemented
|
||||||
--> $DIR/feature-gate-unnamed_fields.rs:3:5
|
--> $DIR/feature-gate-unnamed_fields.rs:4:5
|
||||||
|
|
|
|
||||||
LL | _: union {
|
LL | _: union {
|
||||||
| ^
|
| ^
|
||||||
@ -9,7 +9,7 @@ LL | _: union {
|
|||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: unnamed fields are not yet fully implemented
|
error[E0658]: unnamed fields are not yet fully implemented
|
||||||
--> $DIR/feature-gate-unnamed_fields.rs:3:8
|
--> $DIR/feature-gate-unnamed_fields.rs:4:8
|
||||||
|
|
|
|
||||||
LL | _: union {
|
LL | _: union {
|
||||||
| ________^
|
| ________^
|
||||||
@ -24,7 +24,7 @@ LL | | }
|
|||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: unnamed fields are not yet fully implemented
|
error[E0658]: unnamed fields are not yet fully implemented
|
||||||
--> $DIR/feature-gate-unnamed_fields.rs:12:5
|
--> $DIR/feature-gate-unnamed_fields.rs:14:5
|
||||||
|
|
|
|
||||||
LL | _: struct {
|
LL | _: struct {
|
||||||
| ^
|
| ^
|
||||||
@ -34,7 +34,7 @@ LL | _: struct {
|
|||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: unnamed fields are not yet fully implemented
|
error[E0658]: unnamed fields are not yet fully implemented
|
||||||
--> $DIR/feature-gate-unnamed_fields.rs:12:8
|
--> $DIR/feature-gate-unnamed_fields.rs:14:8
|
||||||
|
|
|
|
||||||
LL | _: struct {
|
LL | _: struct {
|
||||||
| ________^
|
| ________^
|
||||||
@ -49,7 +49,7 @@ LL | | }
|
|||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: unnamed fields are not yet fully implemented
|
error[E0658]: unnamed fields are not yet fully implemented
|
||||||
--> $DIR/feature-gate-unnamed_fields.rs:21:5
|
--> $DIR/feature-gate-unnamed_fields.rs:26:5
|
||||||
|
|
|
|
||||||
LL | _: S
|
LL | _: S
|
||||||
| ^
|
| ^
|
||||||
|
69
tests/ui/union/unnamed-fields/repr_check.rs
Normal file
69
tests/ui/union/unnamed-fields/repr_check.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#![allow(incomplete_features)]
|
||||||
|
#![feature(unnamed_fields)]
|
||||||
|
|
||||||
|
struct A { //~ ERROR struct with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE struct `A` defined here
|
||||||
|
_: struct { //~ NOTE unnamed field defined here
|
||||||
|
a: i32,
|
||||||
|
},
|
||||||
|
_: struct { //~ NOTE unnamed field defined here
|
||||||
|
_: struct {
|
||||||
|
b: i32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
union B { //~ ERROR union with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE union `B` defined here
|
||||||
|
_: union { //~ NOTE unnamed field defined here
|
||||||
|
a: i32,
|
||||||
|
},
|
||||||
|
_: union { //~ NOTE unnamed field defined here
|
||||||
|
_: union {
|
||||||
|
b: i32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct Foo {}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Bar {}
|
||||||
|
//~^ `Bar` defined here
|
||||||
|
//~| `Bar` defined here
|
||||||
|
//~| `Bar` defined here
|
||||||
|
//~| `Bar` defined here
|
||||||
|
|
||||||
|
struct C { //~ ERROR struct with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE struct `C` defined here
|
||||||
|
_: Foo, //~ NOTE unnamed field defined here
|
||||||
|
}
|
||||||
|
|
||||||
|
union D { //~ ERROR union with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE union `D` defined here
|
||||||
|
_: Foo, //~ NOTE unnamed field defined here
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct E {
|
||||||
|
_: Bar, //~ ERROR named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE unnamed field defined here
|
||||||
|
_: struct {
|
||||||
|
_: Bar, //~ ERROR named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE unnamed field defined here
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
union F {
|
||||||
|
_: Bar, //~ ERROR named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE unnamed field defined here
|
||||||
|
_: union {
|
||||||
|
_: Bar, //~ ERROR named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
//~^ NOTE unnamed field defined here
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
108
tests/ui/union/unnamed-fields/repr_check.stderr
Normal file
108
tests/ui/union/unnamed-fields/repr_check.stderr
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
error: struct with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:4:1
|
||||||
|
|
|
||||||
|
LL | struct A {
|
||||||
|
| ^^^^^^^^ struct `A` defined here
|
||||||
|
|
|
||||||
|
note: unnamed field defined here
|
||||||
|
--> $DIR/repr_check.rs:6:5
|
||||||
|
|
|
||||||
|
LL | / _: struct {
|
||||||
|
LL | | a: i32,
|
||||||
|
LL | | },
|
||||||
|
| |_____^
|
||||||
|
note: unnamed field defined here
|
||||||
|
--> $DIR/repr_check.rs:9:5
|
||||||
|
|
|
||||||
|
LL | / _: struct {
|
||||||
|
LL | | _: struct {
|
||||||
|
LL | | b: i32,
|
||||||
|
LL | | },
|
||||||
|
LL | | },
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: union with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:16:1
|
||||||
|
|
|
||||||
|
LL | union B {
|
||||||
|
| ^^^^^^^ union `B` defined here
|
||||||
|
|
|
||||||
|
note: unnamed field defined here
|
||||||
|
--> $DIR/repr_check.rs:18:5
|
||||||
|
|
|
||||||
|
LL | / _: union {
|
||||||
|
LL | | a: i32,
|
||||||
|
LL | | },
|
||||||
|
| |_____^
|
||||||
|
note: unnamed field defined here
|
||||||
|
--> $DIR/repr_check.rs:21:5
|
||||||
|
|
|
||||||
|
LL | / _: union {
|
||||||
|
LL | | _: union {
|
||||||
|
LL | | b: i32,
|
||||||
|
LL | | },
|
||||||
|
LL | | },
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: struct with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:39:1
|
||||||
|
|
|
||||||
|
LL | struct C {
|
||||||
|
| ^^^^^^^^ struct `C` defined here
|
||||||
|
|
|
||||||
|
note: unnamed field defined here
|
||||||
|
--> $DIR/repr_check.rs:41:5
|
||||||
|
|
|
||||||
|
LL | _: Foo,
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: union with unnamed fields must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:44:1
|
||||||
|
|
|
||||||
|
LL | union D {
|
||||||
|
| ^^^^^^^ union `D` defined here
|
||||||
|
|
|
||||||
|
note: unnamed field defined here
|
||||||
|
--> $DIR/repr_check.rs:46:5
|
||||||
|
|
|
||||||
|
LL | _: Foo,
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:51:5
|
||||||
|
|
|
||||||
|
LL | struct Bar {}
|
||||||
|
| ---------- `Bar` defined here
|
||||||
|
...
|
||||||
|
LL | _: Bar,
|
||||||
|
| ^^^^^^ unnamed field defined here
|
||||||
|
|
||||||
|
error: named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:54:9
|
||||||
|
|
|
||||||
|
LL | struct Bar {}
|
||||||
|
| ---------- `Bar` defined here
|
||||||
|
...
|
||||||
|
LL | _: Bar,
|
||||||
|
| ^^^^^^ unnamed field defined here
|
||||||
|
|
||||||
|
error: named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:61:5
|
||||||
|
|
|
||||||
|
LL | struct Bar {}
|
||||||
|
| ---------- `Bar` defined here
|
||||||
|
...
|
||||||
|
LL | _: Bar,
|
||||||
|
| ^^^^^^ unnamed field defined here
|
||||||
|
|
||||||
|
error: named type of unnamed field must have `#[repr(C)]` representation
|
||||||
|
--> $DIR/repr_check.rs:64:9
|
||||||
|
|
|
||||||
|
LL | struct Bar {}
|
||||||
|
| ---------- `Bar` defined here
|
||||||
|
...
|
||||||
|
LL | _: Bar,
|
||||||
|
| ^^^^^^ unnamed field defined here
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user