mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Remove unnamed field feature
This commit is contained in:
parent
8dd5cd0bc1
commit
e3a0da1863
@ -160,14 +160,6 @@ ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
|
||||
.type = inherent impl for this type
|
||||
.only_trait = only trait implementations may be annotated with {$annotation}
|
||||
|
||||
ast_passes_invalid_unnamed_field =
|
||||
unnamed fields are not allowed outside of structs or unions
|
||||
.label = unnamed field declared here
|
||||
|
||||
ast_passes_invalid_unnamed_field_ty =
|
||||
unnamed fields can only have struct or union types
|
||||
.label = not a struct or union
|
||||
|
||||
ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
|
||||
.suggestion = remove safe from this item
|
||||
|
||||
|
@ -255,7 +255,6 @@ impl<'a> AstValidator<'a> {
|
||||
if let Some(ident) = field.ident
|
||||
&& ident.name == kw::Underscore
|
||||
{
|
||||
self.check_unnamed_field_ty(&field.ty, ident.span);
|
||||
self.visit_vis(&field.vis);
|
||||
self.visit_ident(ident);
|
||||
self.visit_ty_common(&field.ty);
|
||||
@ -294,21 +293,6 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_unnamed_field_ty(&self, ty: &Ty, span: Span) {
|
||||
if matches!(
|
||||
&ty.kind,
|
||||
// We already checked for `kw::Underscore` before calling this function,
|
||||
// so skip the check
|
||||
TyKind::AnonStruct(..) | TyKind::AnonUnion(..)
|
||||
// If the anonymous field contains a Path as type, we can't determine
|
||||
// if the path is a valid struct or union, so skip the check
|
||||
| TyKind::Path(..)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
self.dcx().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
|
||||
}
|
||||
|
||||
fn deny_anon_struct_or_union(&self, ty: &Ty) {
|
||||
let struct_or_union = match &ty.kind {
|
||||
TyKind::AnonStruct(..) => "struct",
|
||||
@ -318,15 +302,6 @@ impl<'a> AstValidator<'a> {
|
||||
self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
|
||||
}
|
||||
|
||||
fn deny_unnamed_field(&self, field: &FieldDef) {
|
||||
if let Some(ident) = field.ident
|
||||
&& ident.name == kw::Underscore
|
||||
{
|
||||
self.dcx()
|
||||
.emit_err(errors::InvalidUnnamedField { span: field.span, ident_span: ident.span });
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
|
||||
let Const::Yes(span) = constness else {
|
||||
return;
|
||||
@ -895,7 +870,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn visit_field_def(&mut self, field: &'a FieldDef) {
|
||||
self.deny_unnamed_field(field);
|
||||
visit::walk_field_def(self, field)
|
||||
}
|
||||
|
||||
|
@ -814,24 +814,6 @@ pub(crate) struct NegativeBoundWithParentheticalNotation {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_invalid_unnamed_field_ty)]
|
||||
pub(crate) struct InvalidUnnamedFieldTy {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub ty_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_invalid_unnamed_field)]
|
||||
pub(crate) struct InvalidUnnamedField {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub ident_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
|
||||
pub(crate) struct AnonStructOrUnionNotAllowed {
|
||||
|
@ -541,7 +541,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||
gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
|
||||
gate_all!(explicit_tail_calls, "`become` expression is experimental");
|
||||
gate_all!(generic_const_items, "generic const items are experimental");
|
||||
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
|
||||
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
|
||||
gate_all!(postfix_match, "postfix match is experimental");
|
||||
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
|
||||
|
@ -216,6 +216,8 @@ declare_features! (
|
||||
(removed, test_removed_feature, "1.0.0", None, None),
|
||||
/// Allows using items which are missing stability attributes
|
||||
(removed, unmarked_api, "1.0.0", None, None),
|
||||
/// Allows unnamed fields of struct and union type
|
||||
(removed, unnamed_fields, "1.74.0", Some(49804)),
|
||||
(removed, unsafe_no_drop_flag, "1.0.0", 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),
|
||||
|
@ -618,8 +618,6 @@ declare_features! (
|
||||
/// Allows creation of instances of a struct by moving fields that have
|
||||
/// not changed from prior instances of the same struct (RFC #2528)
|
||||
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
|
||||
/// Allows unnamed fields of struct and union type
|
||||
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
|
||||
/// Allows const generic parameters to be defined with types that
|
||||
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
|
||||
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
|
||||
|
@ -248,8 +248,6 @@ hir_analysis_invalid_union_field =
|
||||
hir_analysis_invalid_union_field_sugg =
|
||||
wrap the field type in `ManuallyDrop<...>`
|
||||
|
||||
hir_analysis_invalid_unnamed_field_ty = unnamed fields can only have struct or union types
|
||||
|
||||
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
|
||||
.label = const parameter declared here
|
||||
|
||||
@ -535,19 +533,6 @@ hir_analysis_unconstrained_generic_parameter = the {$param_def_kind} `{$param_na
|
||||
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
|
||||
.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
|
||||
.suggestion = add `#[repr(C)]` to this {$field_adt_kind}
|
||||
|
||||
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
|
||||
.suggestion = add `#[repr(C)]` to this {$adt_kind}
|
||||
|
||||
hir_analysis_unrecognized_atomic_operation =
|
||||
unrecognized atomic operation function: `{$op}`
|
||||
.label = unrecognized atomic operation
|
||||
|
@ -76,7 +76,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
|
||||
check_transparent(tcx, def);
|
||||
check_packed(tcx, span, def);
|
||||
check_unnamed_fields(tcx, def);
|
||||
}
|
||||
|
||||
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
@ -86,61 +85,6 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
check_transparent(tcx, def);
|
||||
check_union_fields(tcx, span, def_id);
|
||||
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,
|
||||
sugg_span: span.shrink_to_lo(),
|
||||
});
|
||||
}
|
||||
}
|
||||
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_enum()
|
||||
{
|
||||
if !adt.is_anonymous() && !adt.repr().c() {
|
||||
let field_ty_span = tcx.def_span(adt.did());
|
||||
tcx.dcx().emit_err(errors::UnnamedFieldsRepr::FieldMissingReprC {
|
||||
span: tcx.def_span(field.did),
|
||||
field_ty_span,
|
||||
field_ty,
|
||||
field_adt_kind: adt.descr(),
|
||||
sugg_span: field_ty_span.shrink_to_lo(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::InvalidUnnamedFieldTy { span: tcx.def_span(field.did) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the fields of the `union` do not need dropping.
|
||||
|
@ -1007,79 +1007,6 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the uniqueness of fields across adt where there are
|
||||
/// nested fields imported from an unnamed field.
|
||||
fn check_field_in_nested_adt(&mut self, adt_def: ty::AdtDef<'_>, unnamed_field_span: Span) {
|
||||
for field in adt_def.all_fields() {
|
||||
if field.is_unnamed() {
|
||||
// Here we don't care about the generic parameters, so `instantiate_identity` is enough.
|
||||
match self.tcx.type_of(field.did).instantiate_identity().kind() {
|
||||
ty::Adt(adt_def, _) => {
|
||||
self.check_field_in_nested_adt(*adt_def, unnamed_field_span);
|
||||
}
|
||||
ty_kind => span_bug!(
|
||||
self.tcx.def_span(field.did),
|
||||
"Unexpected TyKind in FieldUniquenessCheckContext::check_field_in_nested_adt(): {ty_kind:?}"
|
||||
),
|
||||
}
|
||||
} else {
|
||||
self.check_field_decl(
|
||||
field.ident(self.tcx),
|
||||
NestedSpan {
|
||||
span: unnamed_field_span,
|
||||
nested_field_span: self.tcx.def_span(field.did),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the uniqueness of fields in a struct variant, and recursively
|
||||
/// check the nested fields if it is an unnamed field with type of an
|
||||
/// anonymous adt.
|
||||
fn check_field(&mut self, field: &hir::FieldDef<'_>) {
|
||||
if field.ident.name != kw::Underscore {
|
||||
self.check_field_decl(field.ident, field.span.into());
|
||||
return;
|
||||
}
|
||||
match &field.ty.kind {
|
||||
hir::TyKind::AnonAdt(item_id) => {
|
||||
match &self.tcx.hir_node(item_id.hir_id()).expect_item().kind {
|
||||
hir::ItemKind::Struct(variant_data, ..)
|
||||
| hir::ItemKind::Union(variant_data, ..) => {
|
||||
variant_data.fields().iter().for_each(|f| self.check_field(f));
|
||||
}
|
||||
item_kind => span_bug!(
|
||||
field.ty.span,
|
||||
"Unexpected ItemKind in FieldUniquenessCheckContext::check_field(): {item_kind:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
hir::TyKind::Path(hir::QPath::Resolved(_, hir::Path { res, .. })) => {
|
||||
// If this is a direct path to an ADT, we can check it
|
||||
// If this is a type alias or non-ADT, `check_unnamed_fields` should verify it
|
||||
if let Some(def_id) = res.opt_def_id()
|
||||
&& let Some(local) = def_id.as_local()
|
||||
&& let Node::Item(item) = self.tcx.hir_node_by_def_id(local)
|
||||
&& item.is_adt()
|
||||
{
|
||||
self.check_field_in_nested_adt(self.tcx.adt_def(def_id), field.span);
|
||||
}
|
||||
}
|
||||
// Abort due to errors (there must be an error if an unnamed field
|
||||
// has any type kind other than an anonymous adt or a named adt)
|
||||
ty_kind => {
|
||||
self.tcx.dcx().span_delayed_bug(
|
||||
field.ty.span,
|
||||
format!("Unexpected TyKind in FieldUniquenessCheckContext::check_field(): {ty_kind:?}"),
|
||||
);
|
||||
// FIXME: errors during AST validation should abort the compilation before reaching here.
|
||||
self.tcx.dcx().abort_if_errors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_variant(
|
||||
@ -1090,20 +1017,13 @@ fn lower_variant(
|
||||
def: &hir::VariantData<'_>,
|
||||
adt_kind: ty::AdtKind,
|
||||
parent_did: LocalDefId,
|
||||
is_anonymous: bool,
|
||||
) -> ty::VariantDef {
|
||||
let mut has_unnamed_fields = false;
|
||||
let mut field_uniqueness_check_ctx = FieldUniquenessCheckContext::new(tcx);
|
||||
let fields = def
|
||||
.fields()
|
||||
.iter()
|
||||
.inspect(|f| {
|
||||
has_unnamed_fields |= f.ident.name == kw::Underscore;
|
||||
// We only check named ADT here because anonymous ADTs are checked inside
|
||||
// the named ADT in which they are defined.
|
||||
if !is_anonymous {
|
||||
field_uniqueness_check_ctx.check_field(f);
|
||||
}
|
||||
.inspect(|field| {
|
||||
field_uniqueness_check_ctx.check_field_decl(field.ident, field.span.into());
|
||||
})
|
||||
.map(|f| ty::FieldDef {
|
||||
did: f.def_id.to_def_id(),
|
||||
@ -1127,7 +1047,6 @@ fn lower_variant(
|
||||
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
|
||||
|| variant_did
|
||||
.is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
|
||||
has_unnamed_fields,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1138,20 +1057,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
||||
bug!("expected ADT to be an item");
|
||||
};
|
||||
|
||||
let is_anonymous = item.ident.name == kw::Empty;
|
||||
let repr = if is_anonymous {
|
||||
let parent = tcx.local_parent(def_id);
|
||||
if let Node::Item(item) = tcx.hir_node_by_def_id(parent)
|
||||
&& item.is_struct_or_union()
|
||||
{
|
||||
tcx.adt_def(parent).repr()
|
||||
} else {
|
||||
tcx.dcx().span_delayed_bug(item.span, "anonymous field inside non struct/union");
|
||||
ty::ReprOptions::default()
|
||||
}
|
||||
} else {
|
||||
tcx.repr_options_of_def(def_id)
|
||||
};
|
||||
let repr = tcx.repr_options_of_def(def_id);
|
||||
let (kind, variants) = match &item.kind {
|
||||
ItemKind::Enum(def, _) => {
|
||||
let mut distance_from_explicit = 0;
|
||||
@ -1175,7 +1081,6 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
||||
&v.data,
|
||||
AdtKind::Enum,
|
||||
def_id,
|
||||
is_anonymous,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@ -1195,7 +1100,6 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
||||
def,
|
||||
adt_kind,
|
||||
def_id,
|
||||
is_anonymous,
|
||||
))
|
||||
.collect();
|
||||
|
||||
@ -1203,7 +1107,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
||||
}
|
||||
_ => bug!("{:?} is not an ADT", item.owner_id.def_id),
|
||||
};
|
||||
tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr, is_anonymous)
|
||||
tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
|
||||
}
|
||||
|
||||
fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
||||
|
@ -734,13 +734,6 @@ pub(crate) struct InvalidUnionField {
|
||||
pub note: (),
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_invalid_unnamed_field_ty)]
|
||||
pub(crate) struct InvalidUnnamedFieldTy {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_return_type_notation_on_non_rpitit)]
|
||||
pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
|
||||
@ -1598,41 +1591,6 @@ pub(crate) struct UnconstrainedGenericParameter {
|
||||
pub const_param_note2: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) 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>,
|
||||
#[suggestion(code = "#[repr(C)]\n")]
|
||||
sugg_span: Span,
|
||||
},
|
||||
#[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>,
|
||||
field_adt_kind: &'static str,
|
||||
#[suggestion(code = "#[repr(C)]\n")]
|
||||
sugg_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(hir_analysis_unnamed_fields_repr_field_defined)]
|
||||
pub(crate) struct UnnamedFieldsReprFieldDefined {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
|
||||
pub(crate) struct OpaqueCapturesHigherRankedLifetime {
|
||||
|
@ -33,7 +33,6 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
||||
use rustc_target::abi::{FIRST_VARIANT, FieldIdx};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
||||
use smallvec::SmallVec;
|
||||
use tracing::{debug, instrument, trace};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
@ -1722,8 +1721,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
||||
seen_fields.insert(ident, field.span);
|
||||
// FIXME: handle nested fields
|
||||
self.write_field_index(field.hir_id, i, Vec::new());
|
||||
self.write_field_index(field.hir_id, i);
|
||||
|
||||
// We don't look at stability attributes on
|
||||
// struct-like enums (yet...), but it's definitely not
|
||||
@ -2367,35 +2365,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
base_def: ty::AdtDef<'tcx>,
|
||||
ident: Ident,
|
||||
nested_fields: &mut SmallVec<[(FieldIdx, &'tcx ty::FieldDef); 1]>,
|
||||
) -> bool {
|
||||
) -> Option<(FieldIdx, &'tcx ty::FieldDef)> {
|
||||
// No way to find a field in an enum.
|
||||
if base_def.is_enum() {
|
||||
return false;
|
||||
return None;
|
||||
}
|
||||
|
||||
for (field_idx, field) in base_def.non_enum_variant().fields.iter_enumerated() {
|
||||
if field.is_unnamed() {
|
||||
// We have an unnamed field, recurse into the nested ADT to find `ident`.
|
||||
// If we find it there, return immediately, and `nested_fields` will contain the
|
||||
// correct path.
|
||||
nested_fields.push((field_idx, field));
|
||||
|
||||
let field_ty = self.tcx.type_of(field.did).instantiate_identity();
|
||||
let adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field");
|
||||
if self.find_adt_field(adt_def, ident, &mut *nested_fields) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nested_fields.pop();
|
||||
} else if field.ident(self.tcx).normalize_to_macros_2_0() == ident {
|
||||
if field.ident(self.tcx).normalize_to_macros_2_0() == ident {
|
||||
// We found the field we wanted.
|
||||
nested_fields.push((field_idx, field));
|
||||
return true;
|
||||
return Some((field_idx, field));
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
None
|
||||
}
|
||||
|
||||
// Check field access expressions
|
||||
@ -2425,34 +2408,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return Ty::new_error(self.tcx(), guar);
|
||||
}
|
||||
|
||||
let mut field_path = SmallVec::new();
|
||||
if self.find_adt_field(*base_def, ident, &mut field_path) {
|
||||
let (first_idx, _) = field_path[0];
|
||||
let (_, last_field) = field_path.last().unwrap();
|
||||
|
||||
// Save the index of all fields regardless of their visibility in case
|
||||
// of error recovery.
|
||||
let nested_fields = field_path[..]
|
||||
.array_windows()
|
||||
.map(|[(_, outer), (inner_idx, _)]| {
|
||||
let outer_ty = self.field_ty(expr.span, outer, args);
|
||||
(outer_ty, *inner_idx)
|
||||
})
|
||||
.collect();
|
||||
self.write_field_index(expr.hir_id, first_idx, nested_fields);
|
||||
if let Some((idx, field)) = self.find_adt_field(*base_def, ident) {
|
||||
self.write_field_index(expr.hir_id, idx);
|
||||
|
||||
let adjustments = self.adjust_steps(&autoderef);
|
||||
if last_field.vis.is_accessible_from(def_scope, self.tcx) {
|
||||
if field.vis.is_accessible_from(def_scope, self.tcx) {
|
||||
self.apply_adjustments(base, adjustments);
|
||||
self.register_predicates(autoderef.into_obligations());
|
||||
|
||||
self.tcx.check_stability(
|
||||
last_field.did,
|
||||
Some(expr.hir_id),
|
||||
expr.span,
|
||||
None,
|
||||
);
|
||||
return self.field_ty(expr.span, last_field, args);
|
||||
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
|
||||
return self.field_ty(expr.span, field, args);
|
||||
}
|
||||
|
||||
// The field is not accessible, fall through to error reporting.
|
||||
@ -2467,11 +2432,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.apply_adjustments(base, adjustments);
|
||||
self.register_predicates(autoderef.into_obligations());
|
||||
|
||||
self.write_field_index(
|
||||
expr.hir_id,
|
||||
FieldIdx::from_usize(index),
|
||||
Vec::new(),
|
||||
);
|
||||
self.write_field_index(expr.hir_id, FieldIdx::from_usize(index));
|
||||
return field_ty;
|
||||
}
|
||||
}
|
||||
|
@ -165,16 +165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_field_index(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
index: FieldIdx,
|
||||
nested_fields: Vec<(Ty<'tcx>, FieldIdx)>,
|
||||
) {
|
||||
pub(crate) fn write_field_index(&self, hir_id: HirId, index: FieldIdx) {
|
||||
self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
|
||||
if !nested_fields.is_empty() {
|
||||
self.typeck_results.borrow_mut().nested_fields_mut().insert(hir_id, nested_fields);
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
|
@ -1513,8 +1513,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
field_map
|
||||
.get(&ident)
|
||||
.map(|(i, f)| {
|
||||
// FIXME: handle nested fields
|
||||
self.write_field_index(field.hir_id, *i, Vec::new());
|
||||
self.write_field_index(field.hir_id, *i);
|
||||
self.tcx.check_stability(f.did, Some(pat.hir_id), span, None);
|
||||
self.field_ty(span, f, args)
|
||||
})
|
||||
|
@ -588,11 +588,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
{
|
||||
self.typeck_results.field_indices_mut().insert(hir_id, index);
|
||||
}
|
||||
if let Some(nested_fields) =
|
||||
self.fcx.typeck_results.borrow_mut().nested_fields_mut().remove(hir_id)
|
||||
{
|
||||
self.typeck_results.nested_fields_mut().insert(hir_id, nested_fields);
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, span), level = "debug")]
|
||||
|
@ -1107,8 +1107,6 @@ impl<'a> CrateMetadataRef<'a> {
|
||||
parent_did,
|
||||
None,
|
||||
data.is_non_exhaustive,
|
||||
// FIXME: unnamed fields in crate metadata is unimplemented yet.
|
||||
false,
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -1151,7 +1149,6 @@ impl<'a> CrateMetadataRef<'a> {
|
||||
adt_kind,
|
||||
variants.into_iter().map(|(_, variant)| variant).collect(),
|
||||
repr,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -259,12 +259,8 @@ impl AdtDefData {
|
||||
kind: AdtKind,
|
||||
variants: IndexVec<VariantIdx, VariantDef>,
|
||||
repr: ReprOptions,
|
||||
is_anonymous: bool,
|
||||
) -> Self {
|
||||
debug!(
|
||||
"AdtDef::new({:?}, {:?}, {:?}, {:?}, {:?})",
|
||||
did, kind, variants, repr, is_anonymous
|
||||
);
|
||||
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
|
||||
let mut flags = AdtFlags::NO_ADT_FLAGS;
|
||||
|
||||
if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
|
||||
@ -297,9 +293,6 @@ impl AdtDefData {
|
||||
if tcx.is_lang_item(did, LangItem::UnsafeCell) {
|
||||
flags |= AdtFlags::IS_UNSAFE_CELL;
|
||||
}
|
||||
if is_anonymous {
|
||||
flags |= AdtFlags::IS_ANONYMOUS;
|
||||
}
|
||||
|
||||
AdtDefData { did, variants, flags, repr }
|
||||
}
|
||||
|
@ -1419,16 +1419,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
kind: AdtKind,
|
||||
variants: IndexVec<VariantIdx, ty::VariantDef>,
|
||||
repr: ReprOptions,
|
||||
is_anonymous: bool,
|
||||
) -> ty::AdtDef<'tcx> {
|
||||
self.mk_adt_def_from_data(ty::AdtDefData::new(
|
||||
self,
|
||||
did,
|
||||
kind,
|
||||
variants,
|
||||
repr,
|
||||
is_anonymous,
|
||||
))
|
||||
self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
|
||||
}
|
||||
|
||||
/// Allocates a read-only byte or string literal for `mir::interpret`.
|
||||
|
@ -1155,8 +1155,6 @@ bitflags::bitflags! {
|
||||
const NO_VARIANT_FLAGS = 0;
|
||||
/// Indicates whether the field list of this variant is `#[non_exhaustive]`.
|
||||
const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
|
||||
/// Indicates whether this variant has unnamed fields.
|
||||
const HAS_UNNAMED_FIELDS = 1 << 1;
|
||||
}
|
||||
}
|
||||
rustc_data_structures::external_bitflags_debug! { VariantFlags }
|
||||
@ -1209,12 +1207,11 @@ impl VariantDef {
|
||||
parent_did: DefId,
|
||||
recover_tainted: Option<ErrorGuaranteed>,
|
||||
is_field_list_non_exhaustive: bool,
|
||||
has_unnamed_fields: bool,
|
||||
) -> Self {
|
||||
debug!(
|
||||
"VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?},
|
||||
fields = {:?}, adt_kind = {:?}, parent_did = {:?}, has_unnamed_fields = {:?})",
|
||||
name, variant_did, ctor, discr, fields, adt_kind, parent_did, has_unnamed_fields,
|
||||
fields = {:?}, adt_kind = {:?}, parent_did = {:?})",
|
||||
name, variant_did, ctor, discr, fields, adt_kind, parent_did,
|
||||
);
|
||||
|
||||
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
|
||||
@ -1222,10 +1219,6 @@ impl VariantDef {
|
||||
flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
|
||||
}
|
||||
|
||||
if has_unnamed_fields {
|
||||
flags |= VariantFlags::HAS_UNNAMED_FIELDS;
|
||||
}
|
||||
|
||||
VariantDef {
|
||||
def_id: variant_did.unwrap_or(parent_did),
|
||||
ctor,
|
||||
@ -1243,12 +1236,6 @@ impl VariantDef {
|
||||
self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
|
||||
}
|
||||
|
||||
/// Does this variant contains unnamed fields
|
||||
#[inline]
|
||||
pub fn has_unnamed_fields(&self) -> bool {
|
||||
self.flags.intersects(VariantFlags::HAS_UNNAMED_FIELDS)
|
||||
}
|
||||
|
||||
/// Computes the `Ident` of this variant by looking up the `Span`
|
||||
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
||||
Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
|
||||
@ -1434,11 +1421,6 @@ impl<'tcx> FieldDef {
|
||||
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
||||
Ident::new(self.name, tcx.def_ident_span(self.did).unwrap())
|
||||
}
|
||||
|
||||
/// Returns whether the field is unnamed
|
||||
pub fn is_unnamed(&self) -> bool {
|
||||
self.name == rustc_span::symbol::kw::Underscore
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -42,12 +42,6 @@ pub struct TypeckResults<'tcx> {
|
||||
/// belongs, but it may not exist if it's a tuple field (`tuple.0`).
|
||||
field_indices: ItemLocalMap<FieldIdx>,
|
||||
|
||||
/// Resolved types and indices for the nested fields' accesses of `obj.field` (expanded
|
||||
/// to `obj._(1)._(2).field` in THIR). This map only stores the intermediate type
|
||||
/// of `obj._(1)` and index of `_(1)._(2)`, and the type of `_(1)._(2)`, and the index of
|
||||
/// `_(2).field`.
|
||||
nested_fields: ItemLocalMap<Vec<(Ty<'tcx>, FieldIdx)>>,
|
||||
|
||||
/// Stores the types for various nodes in the AST. Note that this table
|
||||
/// is not guaranteed to be populated outside inference. See
|
||||
/// typeck::check::fn_ctxt for details.
|
||||
@ -225,7 +219,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
||||
hir_owner,
|
||||
type_dependent_defs: Default::default(),
|
||||
field_indices: Default::default(),
|
||||
nested_fields: Default::default(),
|
||||
user_provided_types: Default::default(),
|
||||
user_provided_sigs: Default::default(),
|
||||
node_types: Default::default(),
|
||||
@ -299,18 +292,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
||||
self.field_indices().get(id).cloned()
|
||||
}
|
||||
|
||||
pub fn nested_fields(&self) -> LocalTableInContext<'_, Vec<(Ty<'tcx>, FieldIdx)>> {
|
||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.nested_fields }
|
||||
}
|
||||
|
||||
pub fn nested_fields_mut(&mut self) -> LocalTableInContextMut<'_, Vec<(Ty<'tcx>, FieldIdx)>> {
|
||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.nested_fields }
|
||||
}
|
||||
|
||||
pub fn nested_field_tys_and_indices(&self, id: HirId) -> &[(Ty<'tcx>, FieldIdx)] {
|
||||
self.nested_fields().get(id).map_or(&[], Vec::as_slice)
|
||||
}
|
||||
|
||||
pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
|
||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
|
||||
}
|
||||
|
@ -807,21 +807,11 @@ impl<'tcx> Cx<'tcx> {
|
||||
});
|
||||
ExprKind::Loop { body }
|
||||
}
|
||||
hir::ExprKind::Field(source, ..) => {
|
||||
let mut kind = ExprKind::Field {
|
||||
lhs: self.mirror_expr(source),
|
||||
variant_index: FIRST_VARIANT,
|
||||
name: self.typeck_results.field_index(expr.hir_id),
|
||||
};
|
||||
let nested_field_tys_and_indices =
|
||||
self.typeck_results.nested_field_tys_and_indices(expr.hir_id);
|
||||
for &(ty, idx) in nested_field_tys_and_indices {
|
||||
let expr = Expr { temp_lifetime, ty, span: source.span, kind };
|
||||
let lhs = self.thir.exprs.push(expr);
|
||||
kind = ExprKind::Field { lhs, variant_index: FIRST_VARIANT, name: idx };
|
||||
}
|
||||
kind
|
||||
}
|
||||
hir::ExprKind::Field(source, ..) => ExprKind::Field {
|
||||
lhs: self.mirror_expr(source),
|
||||
variant_index: FIRST_VARIANT,
|
||||
name: self.typeck_results.field_index(expr.hir_id),
|
||||
},
|
||||
hir::ExprKind::Cast(source, cast_ty) => {
|
||||
// Check for a user-given type annotation on this `cast`
|
||||
let user_provided_types = self.typeck_results.user_provided_types();
|
||||
|
@ -2009,9 +2009,7 @@ impl<'a> Parser<'a> {
|
||||
/// for better diagnostics and suggestions.
|
||||
fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
|
||||
let (ident, is_raw) = self.ident_or_err(true)?;
|
||||
if ident.name == kw::Underscore {
|
||||
self.psess.gated_spans.gate(sym::unnamed_fields, lo);
|
||||
} else if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
|
||||
if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
let err = if self.check_fn_front_matter(false, Case::Sensitive) {
|
||||
let inherited_vis =
|
||||
|
@ -1,29 +0,0 @@
|
||||
#[repr(C)]
|
||||
struct Foo {
|
||||
foo: u8,
|
||||
_: union { //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||
//~^ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||
bar: u8,
|
||||
baz: u16
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
union Bar {
|
||||
foobar: u8,
|
||||
_: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||
//~^ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||
foobaz: u8,
|
||||
barbaz: u16
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct S;
|
||||
|
||||
#[repr(C)]
|
||||
struct Baz {
|
||||
_: S //~ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||
}
|
||||
|
||||
fn main(){}
|
@ -1,63 +0,0 @@
|
||||
error[E0658]: unnamed fields are not yet fully implemented
|
||||
--> $DIR/feature-gate-unnamed_fields.rs:4:5
|
||||
|
|
||||
LL | _: union {
|
||||
| ^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
|
||||
= help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
|
||||
= 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
|
||||
--> $DIR/feature-gate-unnamed_fields.rs:4:8
|
||||
|
|
||||
LL | _: union {
|
||||
| ________^
|
||||
LL | |
|
||||
LL | | bar: u8,
|
||||
LL | | baz: u16
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
|
||||
= help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
|
||||
= 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
|
||||
--> $DIR/feature-gate-unnamed_fields.rs:14:5
|
||||
|
|
||||
LL | _: struct {
|
||||
| ^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
|
||||
= help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
|
||||
= 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
|
||||
--> $DIR/feature-gate-unnamed_fields.rs:14:8
|
||||
|
|
||||
LL | _: struct {
|
||||
| ________^
|
||||
LL | |
|
||||
LL | | foobaz: u8,
|
||||
LL | | barbaz: u16
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
|
||||
= help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
|
||||
= 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
|
||||
--> $DIR/feature-gate-unnamed_fields.rs:26:5
|
||||
|
|
||||
LL | _: S
|
||||
| ^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
|
||||
= help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,11 +0,0 @@
|
||||
#![crate_type = "lib"]
|
||||
#![feature(unnamed_fields)]
|
||||
#![allow(unused, incomplete_features)]
|
||||
|
||||
enum K {
|
||||
M {
|
||||
_ : struct { field: u8 },
|
||||
//~^ error: unnamed fields are not allowed outside of structs or unions
|
||||
//~| error: anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
error: unnamed fields are not allowed outside of structs or unions
|
||||
--> $DIR/anon-struct-in-enum-issue-121446.rs:7:9
|
||||
|
|
||||
LL | _ : struct { field: u8 },
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| unnamed field declared here
|
||||
|
||||
error: anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/anon-struct-in-enum-issue-121446.rs:7:13
|
||||
|
|
||||
LL | _ : struct { field: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,18 +0,0 @@
|
||||
#[repr(C)]
|
||||
pub struct GoodStruct(());
|
||||
|
||||
pub struct BadStruct(());
|
||||
|
||||
pub enum BadEnum {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub enum BadEnum2 {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
pub type GoodAlias = GoodStruct;
|
||||
pub type BadAlias = i32;
|
@ -1,337 +0,0 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(unnamed_fields)]
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct Foo {
|
||||
a: u8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct Bar {
|
||||
_: union {
|
||||
a: u8,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
// duplicated with a normal field
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
union A {
|
||||
// referent field
|
||||
a: u8,
|
||||
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
// nested field
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
// more nested field
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
},
|
||||
// nested field in a named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
// duplicated with a nested field
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct B {
|
||||
_: union {
|
||||
// referent field
|
||||
a: u8,
|
||||
|
||||
// normal field (within the same anonymous adt)
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
// nested field (within the same anonymous adt)
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
// more nested field (within the same anonymous adt)
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
},
|
||||
// nested field in a named adt (within the same anonymous adt)
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt (within the same anonymous adt)
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
// nested field
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
// more nested field
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
},
|
||||
// nested field in a named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
// duplicated with a more nested field
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
union C {
|
||||
_: struct {
|
||||
_: union {
|
||||
// referent field
|
||||
a: u8,
|
||||
|
||||
// normal field (within the same anonymous adt)
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
// nested field (within the same anonymous adt)
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
// more nested field (within the same anonymous adt)
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
},
|
||||
// nested field in a named adt (within the same anonymous adt)
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt (within the same anonymous adt)
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
|
||||
// normal field (within the direct outer anonymous adt)
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
// nested field (within the direct outer anonymous adt)
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
// more nested field (within the direct outer anonymous adt)
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
},
|
||||
// nested field in a named adt (within the direct outer anonymous adt)
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt (within the direct outer anonymous adt)
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
// nested field
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
// more nested field
|
||||
_: struct {
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared [E0124]
|
||||
},
|
||||
},
|
||||
// nested field in a named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: union {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
// duplicated with a nested field in a named adt
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct D {
|
||||
// referent field `a`
|
||||
_: Foo,
|
||||
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
// nested field
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
// more nested field
|
||||
_: struct {
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// nested field in another named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: union {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
// duplicated with a nested field in a nested field of a named adt
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
union D2 {
|
||||
// referent field `a`
|
||||
_: Bar,
|
||||
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
// nested field
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
// more nested field
|
||||
_: struct {
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// nested field in another named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: union {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
// duplicated with a nested field in a named adt in an anonymous adt
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct E {
|
||||
_: struct {
|
||||
// referent field `a`
|
||||
_: Foo,
|
||||
|
||||
// normal field (within the same anonymous adt)
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
// nested field (within the same anonymous adt)
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
// more nested field (within the same anonymous adt)
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// nested field in a named adt (within the same anonymous adt)
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt (within the same anonymous adt)
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
// nested field
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
// more nested field
|
||||
_: struct {
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// nested field in another named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: union {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
// duplicated with a nested field in a named adt in an anonymous adt
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
union E2 {
|
||||
_: struct {
|
||||
// referent field `a`
|
||||
_: Bar,
|
||||
|
||||
// normal field (within the same anonymous adt)
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
// nested field (within the same anonymous adt)
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
// more nested field (within the same anonymous adt)
|
||||
_: union {
|
||||
_: struct {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// nested field in a named adt (within the same anonymous adt)
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt (within the same anonymous adt)
|
||||
_: struct {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
|
||||
// normal field
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
// nested field
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
// more nested field
|
||||
_: struct {
|
||||
_: union {
|
||||
a: u8, //~ ERROR field `a` is already declared
|
||||
},
|
||||
},
|
||||
// nested field in another named adt
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
// nested field in a named adt in an anoymous adt
|
||||
_: union {
|
||||
_: Foo, //~ ERROR field `a` is already declared
|
||||
_: Bar, //~ ERROR field `a` is already declared
|
||||
},
|
||||
}
|
||||
|
||||
fn main() {}
|
File diff suppressed because it is too large
Load Diff
@ -1,69 +0,0 @@
|
||||
#![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() {}
|
@ -1,152 +0,0 @@
|
||||
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 | | },
|
||||
| |_____^
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct A {
|
||||
|
|
||||
|
||||
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 | | },
|
||||
| |_____^
|
||||
help: add `#[repr(C)]` to this union
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | union B {
|
||||
|
|
||||
|
||||
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,
|
||||
| ^^^^^^
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct C {
|
||||
|
|
||||
|
||||
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,
|
||||
| ^^^^^^
|
||||
help: add `#[repr(C)]` to this union
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | union D {
|
||||
|
|
||||
|
||||
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
|
||||
|
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct Bar {}
|
||||
|
|
||||
|
||||
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
|
||||
|
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct Bar {}
|
||||
|
|
||||
|
||||
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
|
||||
|
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct Bar {}
|
||||
|
|
||||
|
||||
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
|
||||
|
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct Bar {}
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
@ -1,32 +0,0 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(unnamed_fields)]
|
||||
|
||||
struct F {
|
||||
field1: struct { field2: u8 }, //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
_: struct { field3: u8 },
|
||||
}
|
||||
|
||||
struct G {
|
||||
_: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
|
||||
}
|
||||
|
||||
union H {
|
||||
field1: struct { field2: u8 }, //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
_: struct { field3: u8 },
|
||||
}
|
||||
|
||||
union I {
|
||||
_: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
|
||||
}
|
||||
|
||||
enum K {
|
||||
M {
|
||||
_ : struct { field: u8 }, //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
//~^ ERROR unnamed fields are not allowed outside of structs or unions
|
||||
},
|
||||
N {
|
||||
_ : u8, //~ ERROR unnamed fields are not allowed outside of structs or unions
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,48 +0,0 @@
|
||||
error: anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/restrict_anonymous_structs.rs:5:13
|
||||
|
|
||||
LL | field1: struct { field2: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_anonymous_structs.rs:10:5
|
||||
|
|
||||
LL | _: (u8, u8),
|
||||
| ^ -------- not a struct or union
|
||||
|
||||
error: anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/restrict_anonymous_structs.rs:14:13
|
||||
|
|
||||
LL | field1: struct { field2: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_anonymous_structs.rs:19:5
|
||||
|
|
||||
LL | _: (u8, u8),
|
||||
| ^ -------- not a struct or union
|
||||
|
||||
error: unnamed fields are not allowed outside of structs or unions
|
||||
--> $DIR/restrict_anonymous_structs.rs:24:9
|
||||
|
|
||||
LL | _ : struct { field: u8 },
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| unnamed field declared here
|
||||
|
||||
error: anonymous structs are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/restrict_anonymous_structs.rs:24:13
|
||||
|
|
||||
LL | _ : struct { field: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
|
||||
|
||||
error: unnamed fields are not allowed outside of structs or unions
|
||||
--> $DIR/restrict_anonymous_structs.rs:28:9
|
||||
|
|
||||
LL | _ : u8,
|
||||
| -^^^^^
|
||||
| |
|
||||
| unnamed field declared here
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
@ -1,32 +0,0 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(unnamed_fields)]
|
||||
|
||||
struct F {
|
||||
field1: union { field2: u8 }, //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
|
||||
_: union { field3: u8 },
|
||||
}
|
||||
|
||||
struct G {
|
||||
_: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
|
||||
}
|
||||
|
||||
union H {
|
||||
field1: union { field2: u8 }, //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
|
||||
_: union { field3: u8 },
|
||||
}
|
||||
|
||||
union I {
|
||||
_: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
|
||||
}
|
||||
|
||||
enum K {
|
||||
M {
|
||||
_ : union { field: u8 }, //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
|
||||
//~^ ERROR unnamed fields are not allowed outside of structs or unions
|
||||
},
|
||||
N {
|
||||
_ : u8, //~ ERROR unnamed fields are not allowed outside of structs or unions
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,48 +0,0 @@
|
||||
error: anonymous unions are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/restrict_anonymous_unions.rs:5:13
|
||||
|
|
||||
LL | field1: union { field2: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^^ anonymous union declared here
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_anonymous_unions.rs:10:5
|
||||
|
|
||||
LL | _: (u8, u8),
|
||||
| ^ -------- not a struct or union
|
||||
|
||||
error: anonymous unions are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/restrict_anonymous_unions.rs:14:13
|
||||
|
|
||||
LL | field1: union { field2: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^^ anonymous union declared here
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_anonymous_unions.rs:19:5
|
||||
|
|
||||
LL | _: (u8, u8),
|
||||
| ^ -------- not a struct or union
|
||||
|
||||
error: unnamed fields are not allowed outside of structs or unions
|
||||
--> $DIR/restrict_anonymous_unions.rs:24:9
|
||||
|
|
||||
LL | _ : union { field: u8 },
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| unnamed field declared here
|
||||
|
||||
error: anonymous unions are not allowed outside of unnamed struct or union fields
|
||||
--> $DIR/restrict_anonymous_unions.rs:24:13
|
||||
|
|
||||
LL | _ : union { field: u8 },
|
||||
| ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
|
||||
|
||||
error: unnamed fields are not allowed outside of structs or unions
|
||||
--> $DIR/restrict_anonymous_unions.rs:28:9
|
||||
|
|
||||
LL | _ : u8,
|
||||
| -^^^^^
|
||||
| |
|
||||
| unnamed field declared here
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
@ -1,44 +0,0 @@
|
||||
//@ aux-build:dep.rs
|
||||
|
||||
// test for #121151
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(unnamed_fields)]
|
||||
|
||||
extern crate dep;
|
||||
|
||||
#[repr(C)]
|
||||
struct A {
|
||||
a: u8,
|
||||
}
|
||||
|
||||
enum BadEnum {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
enum BadEnum2 {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
type MyStruct = A;
|
||||
type MyI32 = i32;
|
||||
|
||||
#[repr(C)]
|
||||
struct L {
|
||||
_: i32, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: MyI32, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: BadEnum, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: BadEnum2, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: MyStruct,
|
||||
_: dep::BadStruct, //~ ERROR named type of unnamed field must have `#[repr(C)]` representation
|
||||
_: dep::BadEnum, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: dep::BadEnum2, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: dep::BadAlias, //~ ERROR unnamed fields can only have struct or union types
|
||||
_: dep::GoodAlias,
|
||||
_: dep::GoodStruct,
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,62 +0,0 @@
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:31:5
|
||||
|
|
||||
LL | _: i32,
|
||||
| ^^^^^^
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:32:5
|
||||
|
|
||||
LL | _: MyI32,
|
||||
| ^^^^^^^^
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:33:5
|
||||
|
|
||||
LL | _: BadEnum,
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:34:5
|
||||
|
|
||||
LL | _: BadEnum2,
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: named type of unnamed field must have `#[repr(C)]` representation
|
||||
--> $DIR/restrict_type_hir.rs:36:5
|
||||
|
|
||||
LL | _: dep::BadStruct,
|
||||
| ^^^^^^^^^^^^^^^^^ unnamed field defined here
|
||||
|
|
||||
::: $DIR/auxiliary/dep.rs:4:1
|
||||
|
|
||||
LL | pub struct BadStruct(());
|
||||
| -------------------- `BadStruct` defined here
|
||||
|
|
||||
help: add `#[repr(C)]` to this struct
|
||||
--> $DIR/auxiliary/dep.rs:4:1
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | pub struct BadStruct(());
|
||||
|
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:37:5
|
||||
|
|
||||
LL | _: dep::BadEnum,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:38:5
|
||||
|
|
||||
LL | _: dep::BadEnum2,
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/restrict_type_hir.rs:39:5
|
||||
|
|
||||
LL | _: dep::BadAlias,
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
@ -1,25 +0,0 @@
|
||||
type NodeId = u32;
|
||||
struct Type<'a>(std::marker::PhantomData::<&'a ()>);
|
||||
|
||||
type Ast<'ast> = &'ast AstStructure<'ast>;
|
||||
|
||||
struct AstStructure<'ast> {
|
||||
//~^ ERROR struct with unnamed fields must have `#[repr(C)]` representation
|
||||
id: NodeId,
|
||||
_: AstKind<'ast>
|
||||
//~^ ERROR unnamed fields are not yet fully implemented [E0658]
|
||||
//~^^ ERROR unnamed fields can only have struct or union types
|
||||
}
|
||||
|
||||
enum AstKind<'ast> {
|
||||
ExprInt,
|
||||
ExprLambda(Ast<'ast>),
|
||||
}
|
||||
|
||||
fn compute_types<'tcx,'ast>(ast: Ast<'ast>) -> Type<'tcx>
|
||||
{
|
||||
match ast.kind {}
|
||||
//~^ ERROR no field `kind` on type `&'ast AstStructure<'ast>` [E0609]
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,45 +0,0 @@
|
||||
error[E0658]: unnamed fields are not yet fully implemented
|
||||
--> $DIR/unnamed-enum-field-issue-121757.rs:9:5
|
||||
|
|
||||
LL | _: AstKind<'ast>
|
||||
| ^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
|
||||
= help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: struct with unnamed fields must have `#[repr(C)]` representation
|
||||
--> $DIR/unnamed-enum-field-issue-121757.rs:6:1
|
||||
|
|
||||
LL | struct AstStructure<'ast> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ struct `AstStructure` defined here
|
||||
|
|
||||
note: unnamed field defined here
|
||||
--> $DIR/unnamed-enum-field-issue-121757.rs:9:5
|
||||
|
|
||||
LL | _: AstKind<'ast>
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
help: add `#[repr(C)]` to this struct
|
||||
|
|
||||
LL + #[repr(C)]
|
||||
LL | struct AstStructure<'ast> {
|
||||
|
|
||||
|
||||
error: unnamed fields can only have struct or union types
|
||||
--> $DIR/unnamed-enum-field-issue-121757.rs:9:5
|
||||
|
|
||||
LL | _: AstKind<'ast>
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0609]: no field `kind` on type `&'ast AstStructure<'ast>`
|
||||
--> $DIR/unnamed-enum-field-issue-121757.rs:21:15
|
||||
|
|
||||
LL | match ast.kind {}
|
||||
| ^^^^ unknown field
|
||||
|
|
||||
= note: available fields are: `id`, `_`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0609, E0658.
|
||||
For more information about an error, try `rustc --explain E0609`.
|
@ -786,20 +786,6 @@ mod types {
|
||||
let _: (T, T);
|
||||
}
|
||||
|
||||
/// TyKind::AnonStruct
|
||||
fn ty_anon_struct() {
|
||||
struct Struct {
|
||||
_: struct { t: T },
|
||||
}
|
||||
}
|
||||
|
||||
/// TyKind::AnonUnion
|
||||
fn ty_anon_union() {
|
||||
struct Struct {
|
||||
_: union { t: T },
|
||||
}
|
||||
}
|
||||
|
||||
/// TyKind::Path
|
||||
fn ty_path() {
|
||||
let _: T;
|
||||
|
@ -361,8 +361,6 @@ mod expressions {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -636,22 +634,6 @@ mod types {
|
||||
fn ty_never() { let _: !; }
|
||||
/// TyKind::Tup
|
||||
fn ty_tup() { let _: (); let _: (T,); let _: (T, T); }
|
||||
/// TyKind::AnonStruct
|
||||
fn ty_anon_struct() {
|
||||
struct Struct {
|
||||
_: struct {
|
||||
t: T,
|
||||
},
|
||||
}
|
||||
}
|
||||
/// TyKind::AnonUnion
|
||||
fn ty_anon_union() {
|
||||
struct Struct {
|
||||
_: union {
|
||||
t: T,
|
||||
},
|
||||
}
|
||||
}
|
||||
/// TyKind::Path
|
||||
fn ty_path() {
|
||||
let _: T;
|
||||
|
Loading…
Reference in New Issue
Block a user