mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +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
|
.type = inherent impl for this type
|
||||||
.only_trait = only trait implementations may be annotated with {$annotation}
|
.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
|
ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
|
||||||
.suggestion = remove safe from this item
|
.suggestion = remove safe from this item
|
||||||
|
|
||||||
|
@ -255,7 +255,6 @@ impl<'a> AstValidator<'a> {
|
|||||||
if let Some(ident) = field.ident
|
if let Some(ident) = field.ident
|
||||||
&& ident.name == kw::Underscore
|
&& ident.name == kw::Underscore
|
||||||
{
|
{
|
||||||
self.check_unnamed_field_ty(&field.ty, ident.span);
|
|
||||||
self.visit_vis(&field.vis);
|
self.visit_vis(&field.vis);
|
||||||
self.visit_ident(ident);
|
self.visit_ident(ident);
|
||||||
self.visit_ty_common(&field.ty);
|
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) {
|
fn deny_anon_struct_or_union(&self, ty: &Ty) {
|
||||||
let struct_or_union = match &ty.kind {
|
let struct_or_union = match &ty.kind {
|
||||||
TyKind::AnonStruct(..) => "struct",
|
TyKind::AnonStruct(..) => "struct",
|
||||||
@ -318,15 +302,6 @@ impl<'a> AstValidator<'a> {
|
|||||||
self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
|
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) {
|
fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
|
||||||
let Const::Yes(span) = constness else {
|
let Const::Yes(span) = constness else {
|
||||||
return;
|
return;
|
||||||
@ -895,7 +870,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_field_def(&mut self, field: &'a FieldDef) {
|
fn visit_field_def(&mut self, field: &'a FieldDef) {
|
||||||
self.deny_unnamed_field(field);
|
|
||||||
visit::walk_field_def(self, field)
|
visit::walk_field_def(self, field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,24 +814,6 @@ pub(crate) struct NegativeBoundWithParentheticalNotation {
|
|||||||
pub span: Span,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
|
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
|
||||||
pub(crate) struct AnonStructOrUnionNotAllowed {
|
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!(builtin_syntax, "`builtin #` syntax is unstable");
|
||||||
gate_all!(explicit_tail_calls, "`become` expression is experimental");
|
gate_all!(explicit_tail_calls, "`become` expression is experimental");
|
||||||
gate_all!(generic_const_items, "generic const items are 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!(fn_delegation, "functions delegation is not yet fully implemented");
|
||||||
gate_all!(postfix_match, "postfix match is experimental");
|
gate_all!(postfix_match, "postfix match is experimental");
|
||||||
gate_all!(mut_ref, "mutable by-reference bindings are 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),
|
(removed, test_removed_feature, "1.0.0", None, None),
|
||||||
/// Allows using items which are missing stability attributes
|
/// Allows using items which are missing stability attributes
|
||||||
(removed, unmarked_api, "1.0.0", None, None),
|
(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),
|
(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.
|
/// 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),
|
(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
|
/// Allows creation of instances of a struct by moving fields that have
|
||||||
/// not changed from prior instances of the same struct (RFC #2528)
|
/// not changed from prior instances of the same struct (RFC #2528)
|
||||||
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
|
(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
|
/// Allows const generic parameters to be defined with types that
|
||||||
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
|
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
|
||||||
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
|
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
|
||||||
|
@ -248,8 +248,6 @@ hir_analysis_invalid_union_field =
|
|||||||
hir_analysis_invalid_union_field_sugg =
|
hir_analysis_invalid_union_field_sugg =
|
||||||
wrap the field type in `ManuallyDrop<...>`
|
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
|
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
|
||||||
.label = const parameter declared here
|
.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
|
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
|
|
||||||
.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 =
|
hir_analysis_unrecognized_atomic_operation =
|
||||||
unrecognized atomic operation function: `{$op}`
|
unrecognized atomic operation function: `{$op}`
|
||||||
.label = unrecognized atomic operation
|
.label = unrecognized atomic operation
|
||||||
|
@ -76,7 +76,6 @@ 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) {
|
||||||
@ -86,61 +85,6 @@ 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,
|
|
||||||
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.
|
/// 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(
|
fn lower_variant(
|
||||||
@ -1090,20 +1017,13 @@ fn lower_variant(
|
|||||||
def: &hir::VariantData<'_>,
|
def: &hir::VariantData<'_>,
|
||||||
adt_kind: ty::AdtKind,
|
adt_kind: ty::AdtKind,
|
||||||
parent_did: LocalDefId,
|
parent_did: LocalDefId,
|
||||||
is_anonymous: bool,
|
|
||||||
) -> ty::VariantDef {
|
) -> ty::VariantDef {
|
||||||
let mut has_unnamed_fields = false;
|
|
||||||
let mut field_uniqueness_check_ctx = FieldUniquenessCheckContext::new(tcx);
|
let mut field_uniqueness_check_ctx = FieldUniquenessCheckContext::new(tcx);
|
||||||
let fields = def
|
let fields = def
|
||||||
.fields()
|
.fields()
|
||||||
.iter()
|
.iter()
|
||||||
.inspect(|f| {
|
.inspect(|field| {
|
||||||
has_unnamed_fields |= f.ident.name == kw::Underscore;
|
field_uniqueness_check_ctx.check_field_decl(field.ident, field.span.into());
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|f| ty::FieldDef {
|
.map(|f| ty::FieldDef {
|
||||||
did: f.def_id.to_def_id(),
|
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)
|
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
|
||||||
|| variant_did
|
|| variant_did
|
||||||
.is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
|
.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");
|
bug!("expected ADT to be an item");
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_anonymous = item.ident.name == kw::Empty;
|
let repr = tcx.repr_options_of_def(def_id);
|
||||||
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 (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;
|
||||||
@ -1175,7 +1081,6 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
|||||||
&v.data,
|
&v.data,
|
||||||
AdtKind::Enum,
|
AdtKind::Enum,
|
||||||
def_id,
|
def_id,
|
||||||
is_anonymous,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -1195,7 +1100,6 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
|||||||
def,
|
def,
|
||||||
adt_kind,
|
adt_kind,
|
||||||
def_id,
|
def_id,
|
||||||
is_anonymous,
|
|
||||||
))
|
))
|
||||||
.collect();
|
.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),
|
_ => 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 {
|
fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
||||||
|
@ -734,13 +734,6 @@ pub(crate) struct InvalidUnionField {
|
|||||||
pub note: (),
|
pub note: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_invalid_unnamed_field_ty)]
|
|
||||||
pub(crate) struct InvalidUnnamedFieldTy {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_return_type_notation_on_non_rpitit)]
|
#[diag(hir_analysis_return_type_notation_on_non_rpitit)]
|
||||||
pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
|
pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
|
||||||
@ -1598,41 +1591,6 @@ pub(crate) struct UnconstrainedGenericParameter {
|
|||||||
pub const_param_note2: bool,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
|
#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
|
||||||
pub(crate) struct OpaqueCapturesHigherRankedLifetime {
|
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_target::abi::{FIRST_VARIANT, FieldIdx};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
||||||
use smallvec::SmallVec;
|
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
use {rustc_ast as ast, rustc_hir as hir};
|
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 ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||||
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
||||||
seen_fields.insert(ident, field.span);
|
seen_fields.insert(ident, field.span);
|
||||||
// FIXME: handle nested fields
|
self.write_field_index(field.hir_id, i);
|
||||||
self.write_field_index(field.hir_id, i, Vec::new());
|
|
||||||
|
|
||||||
// We don't look at stability attributes on
|
// We don't look at stability attributes on
|
||||||
// struct-like enums (yet...), but it's definitely not
|
// struct-like enums (yet...), but it's definitely not
|
||||||
@ -2367,35 +2365,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
base_def: ty::AdtDef<'tcx>,
|
base_def: ty::AdtDef<'tcx>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
nested_fields: &mut SmallVec<[(FieldIdx, &'tcx ty::FieldDef); 1]>,
|
) -> Option<(FieldIdx, &'tcx ty::FieldDef)> {
|
||||||
) -> bool {
|
|
||||||
// No way to find a field in an enum.
|
// No way to find a field in an enum.
|
||||||
if base_def.is_enum() {
|
if base_def.is_enum() {
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (field_idx, field) in base_def.non_enum_variant().fields.iter_enumerated() {
|
for (field_idx, field) in base_def.non_enum_variant().fields.iter_enumerated() {
|
||||||
if field.is_unnamed() {
|
if field.ident(self.tcx).normalize_to_macros_2_0() == ident {
|
||||||
// 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 {
|
|
||||||
// We found the field we wanted.
|
// We found the field we wanted.
|
||||||
nested_fields.push((field_idx, field));
|
return Some((field_idx, field));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check field access expressions
|
// Check field access expressions
|
||||||
@ -2425,34 +2408,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
return Ty::new_error(self.tcx(), guar);
|
return Ty::new_error(self.tcx(), guar);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut field_path = SmallVec::new();
|
if let Some((idx, field)) = self.find_adt_field(*base_def, ident) {
|
||||||
if self.find_adt_field(*base_def, ident, &mut field_path) {
|
self.write_field_index(expr.hir_id, idx);
|
||||||
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);
|
|
||||||
|
|
||||||
let adjustments = self.adjust_steps(&autoderef);
|
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.apply_adjustments(base, adjustments);
|
||||||
self.register_predicates(autoderef.into_obligations());
|
self.register_predicates(autoderef.into_obligations());
|
||||||
|
|
||||||
self.tcx.check_stability(
|
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
|
||||||
last_field.did,
|
return self.field_ty(expr.span, field, args);
|
||||||
Some(expr.hir_id),
|
|
||||||
expr.span,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
return self.field_ty(expr.span, last_field, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The field is not accessible, fall through to error reporting.
|
// 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.apply_adjustments(base, adjustments);
|
||||||
self.register_predicates(autoderef.into_obligations());
|
self.register_predicates(autoderef.into_obligations());
|
||||||
|
|
||||||
self.write_field_index(
|
self.write_field_index(expr.hir_id, FieldIdx::from_usize(index));
|
||||||
expr.hir_id,
|
|
||||||
FieldIdx::from_usize(index),
|
|
||||||
Vec::new(),
|
|
||||||
);
|
|
||||||
return field_ty;
|
return field_ty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,16 +165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn write_field_index(
|
pub(crate) fn write_field_index(&self, hir_id: HirId, index: FieldIdx) {
|
||||||
&self,
|
|
||||||
hir_id: HirId,
|
|
||||||
index: FieldIdx,
|
|
||||||
nested_fields: Vec<(Ty<'tcx>, FieldIdx)>,
|
|
||||||
) {
|
|
||||||
self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
|
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))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
@ -1513,8 +1513,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
field_map
|
field_map
|
||||||
.get(&ident)
|
.get(&ident)
|
||||||
.map(|(i, f)| {
|
.map(|(i, f)| {
|
||||||
// FIXME: handle nested fields
|
self.write_field_index(field.hir_id, *i);
|
||||||
self.write_field_index(field.hir_id, *i, Vec::new());
|
|
||||||
self.tcx.check_stability(f.did, Some(pat.hir_id), span, None);
|
self.tcx.check_stability(f.did, Some(pat.hir_id), span, None);
|
||||||
self.field_ty(span, f, args)
|
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);
|
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")]
|
#[instrument(skip(self, span), level = "debug")]
|
||||||
|
@ -1107,8 +1107,6 @@ impl<'a> CrateMetadataRef<'a> {
|
|||||||
parent_did,
|
parent_did,
|
||||||
None,
|
None,
|
||||||
data.is_non_exhaustive,
|
data.is_non_exhaustive,
|
||||||
// FIXME: unnamed fields in crate metadata is unimplemented yet.
|
|
||||||
false,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1151,7 +1149,6 @@ impl<'a> CrateMetadataRef<'a> {
|
|||||||
adt_kind,
|
adt_kind,
|
||||||
variants.into_iter().map(|(_, variant)| variant).collect(),
|
variants.into_iter().map(|(_, variant)| variant).collect(),
|
||||||
repr,
|
repr,
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,12 +259,8 @@ impl AdtDefData {
|
|||||||
kind: AdtKind,
|
kind: AdtKind,
|
||||||
variants: IndexVec<VariantIdx, VariantDef>,
|
variants: IndexVec<VariantIdx, VariantDef>,
|
||||||
repr: ReprOptions,
|
repr: ReprOptions,
|
||||||
is_anonymous: bool,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
debug!(
|
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
|
||||||
"AdtDef::new({:?}, {:?}, {:?}, {:?}, {:?})",
|
|
||||||
did, kind, variants, repr, is_anonymous
|
|
||||||
);
|
|
||||||
let mut flags = AdtFlags::NO_ADT_FLAGS;
|
let mut flags = AdtFlags::NO_ADT_FLAGS;
|
||||||
|
|
||||||
if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
|
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) {
|
if tcx.is_lang_item(did, LangItem::UnsafeCell) {
|
||||||
flags |= AdtFlags::IS_UNSAFE_CELL;
|
flags |= AdtFlags::IS_UNSAFE_CELL;
|
||||||
}
|
}
|
||||||
if is_anonymous {
|
|
||||||
flags |= AdtFlags::IS_ANONYMOUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdtDefData { did, variants, flags, repr }
|
AdtDefData { did, variants, flags, repr }
|
||||||
}
|
}
|
||||||
|
@ -1419,16 +1419,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
kind: AdtKind,
|
kind: AdtKind,
|
||||||
variants: IndexVec<VariantIdx, ty::VariantDef>,
|
variants: IndexVec<VariantIdx, ty::VariantDef>,
|
||||||
repr: ReprOptions,
|
repr: ReprOptions,
|
||||||
is_anonymous: bool,
|
|
||||||
) -> ty::AdtDef<'tcx> {
|
) -> ty::AdtDef<'tcx> {
|
||||||
self.mk_adt_def_from_data(ty::AdtDefData::new(
|
self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
|
||||||
self,
|
|
||||||
did,
|
|
||||||
kind,
|
|
||||||
variants,
|
|
||||||
repr,
|
|
||||||
is_anonymous,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a read-only byte or string literal for `mir::interpret`.
|
/// Allocates a read-only byte or string literal for `mir::interpret`.
|
||||||
|
@ -1155,8 +1155,6 @@ bitflags::bitflags! {
|
|||||||
const NO_VARIANT_FLAGS = 0;
|
const NO_VARIANT_FLAGS = 0;
|
||||||
/// Indicates whether the field list of this variant is `#[non_exhaustive]`.
|
/// Indicates whether the field list of this variant is `#[non_exhaustive]`.
|
||||||
const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
|
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 }
|
rustc_data_structures::external_bitflags_debug! { VariantFlags }
|
||||||
@ -1209,12 +1207,11 @@ impl VariantDef {
|
|||||||
parent_did: DefId,
|
parent_did: DefId,
|
||||||
recover_tainted: Option<ErrorGuaranteed>,
|
recover_tainted: Option<ErrorGuaranteed>,
|
||||||
is_field_list_non_exhaustive: bool,
|
is_field_list_non_exhaustive: bool,
|
||||||
has_unnamed_fields: bool,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
debug!(
|
debug!(
|
||||||
"VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?},
|
"VariantDef::new(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, has_unnamed_fields,
|
name, variant_did, ctor, discr, fields, adt_kind, parent_did,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
|
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
|
||||||
@ -1222,10 +1219,6 @@ impl VariantDef {
|
|||||||
flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
|
flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_unnamed_fields {
|
|
||||||
flags |= VariantFlags::HAS_UNNAMED_FIELDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VariantDef {
|
VariantDef {
|
||||||
def_id: variant_did.unwrap_or(parent_did),
|
def_id: variant_did.unwrap_or(parent_did),
|
||||||
ctor,
|
ctor,
|
||||||
@ -1243,12 +1236,6 @@ impl VariantDef {
|
|||||||
self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
|
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`
|
/// Computes the `Ident` of this variant by looking up the `Span`
|
||||||
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
||||||
Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
|
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 {
|
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
||||||
Ident::new(self.name, tcx.def_ident_span(self.did).unwrap())
|
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)]
|
#[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`).
|
/// belongs, but it may not exist if it's a tuple field (`tuple.0`).
|
||||||
field_indices: ItemLocalMap<FieldIdx>,
|
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
|
/// Stores the types for various nodes in the AST. Note that this table
|
||||||
/// is not guaranteed to be populated outside inference. See
|
/// is not guaranteed to be populated outside inference. See
|
||||||
/// typeck::check::fn_ctxt for details.
|
/// typeck::check::fn_ctxt for details.
|
||||||
@ -225,7 +219,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||||||
hir_owner,
|
hir_owner,
|
||||||
type_dependent_defs: Default::default(),
|
type_dependent_defs: Default::default(),
|
||||||
field_indices: Default::default(),
|
field_indices: Default::default(),
|
||||||
nested_fields: Default::default(),
|
|
||||||
user_provided_types: Default::default(),
|
user_provided_types: Default::default(),
|
||||||
user_provided_sigs: Default::default(),
|
user_provided_sigs: Default::default(),
|
||||||
node_types: Default::default(),
|
node_types: Default::default(),
|
||||||
@ -299,18 +292,6 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||||||
self.field_indices().get(id).cloned()
|
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>> {
|
pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
|
||||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
|
LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
|
||||||
}
|
}
|
||||||
|
@ -807,21 +807,11 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
});
|
});
|
||||||
ExprKind::Loop { body }
|
ExprKind::Loop { body }
|
||||||
}
|
}
|
||||||
hir::ExprKind::Field(source, ..) => {
|
hir::ExprKind::Field(source, ..) => ExprKind::Field {
|
||||||
let mut kind = ExprKind::Field {
|
lhs: self.mirror_expr(source),
|
||||||
lhs: self.mirror_expr(source),
|
variant_index: FIRST_VARIANT,
|
||||||
variant_index: FIRST_VARIANT,
|
name: self.typeck_results.field_index(expr.hir_id),
|
||||||
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::Cast(source, cast_ty) => {
|
hir::ExprKind::Cast(source, cast_ty) => {
|
||||||
// Check for a user-given type annotation on this `cast`
|
// Check for a user-given type annotation on this `cast`
|
||||||
let user_provided_types = self.typeck_results.user_provided_types();
|
let user_provided_types = self.typeck_results.user_provided_types();
|
||||||
|
@ -2009,9 +2009,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// for better diagnostics and suggestions.
|
/// for better diagnostics and suggestions.
|
||||||
fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
|
fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
|
||||||
let (ident, is_raw) = self.ident_or_err(true)?;
|
let (ident, is_raw) = self.ident_or_err(true)?;
|
||||||
if ident.name == kw::Underscore {
|
if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
|
||||||
self.psess.gated_spans.gate(sym::unnamed_fields, lo);
|
|
||||||
} else if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
|
|
||||||
let snapshot = self.create_snapshot_for_diagnostic();
|
let snapshot = self.create_snapshot_for_diagnostic();
|
||||||
let err = if self.check_fn_front_matter(false, Case::Sensitive) {
|
let err = if self.check_fn_front_matter(false, Case::Sensitive) {
|
||||||
let inherited_vis =
|
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);
|
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
|
/// TyKind::Path
|
||||||
fn ty_path() {
|
fn ty_path() {
|
||||||
let _: T;
|
let _: T;
|
||||||
|
@ -361,8 +361,6 @@ mod expressions {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -636,22 +634,6 @@ mod types {
|
|||||||
fn ty_never() { let _: !; }
|
fn ty_never() { let _: !; }
|
||||||
/// TyKind::Tup
|
/// TyKind::Tup
|
||||||
fn ty_tup() { let _: (); let _: (T,); let _: (T, T); }
|
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
|
/// TyKind::Path
|
||||||
fn ty_path() {
|
fn ty_path() {
|
||||||
let _: T;
|
let _: T;
|
||||||
|
Loading…
Reference in New Issue
Block a user