From d0165956fe070d12090896aa5546e509045471eb Mon Sep 17 00:00:00 2001 From: surechen Date: Thu, 26 Sep 2024 12:35:44 +0800 Subject: Add suggestion for removing invalid path separator `::` in function definition. for example: `fn invalid_path_separator::() {}` fixes: #130791 --- compiler/rustc_parse/src/parser/generics.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index b9256daa725..5aebe716b0a 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -269,6 +269,13 @@ impl<'a> Parser<'a> { /// | ( < lifetimes , typaramseq ( , )? > ) /// where typaramseq = ( typaram ) | ( typaram , typaramseq ) pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> { + // invalid path separator `::` in function definition + // for example `fn invalid_path_separator::() {}` + if self.eat_noexpect(&token::PathSep) { + self.dcx() + .emit_err(errors::InvalidPathSepInFnDefinition { span: self.prev_token.span }); + } + let span_lo = self.token.span; let (params, span) = if self.eat_lt() { let params = self.parse_generic_params()?; -- cgit 1.4.1-3-g733a5 From e3a0da18633a8cfb5263bb975747352690b01fcf Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 22:10:16 -0400 Subject: Remove unnamed field feature --- compiler/rustc_ast_passes/messages.ftl | 8 - compiler/rustc_ast_passes/src/ast_validation.rs | 26 - compiler/rustc_ast_passes/src/errors.rs | 18 - compiler/rustc_ast_passes/src/feature_gate.rs | 1 - compiler/rustc_feature/src/removed.rs | 2 + compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_hir_analysis/messages.ftl | 15 - compiler/rustc_hir_analysis/src/check/check.rs | 56 - compiler/rustc_hir_analysis/src/collect.rs | 104 +- compiler/rustc_hir_analysis/src/errors.rs | 42 - compiler/rustc_hir_typeck/src/expr.rs | 63 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 10 +- compiler/rustc_hir_typeck/src/pat.rs | 3 +- compiler/rustc_hir_typeck/src/writeback.rs | 5 - compiler/rustc_metadata/src/rmeta/decoder.rs | 3 - compiler/rustc_middle/src/ty/adt.rs | 9 +- compiler/rustc_middle/src/ty/context.rs | 10 +- compiler/rustc_middle/src/ty/mod.rs | 22 +- compiler/rustc_middle/src/ty/typeck_results.rs | 19 - compiler/rustc_mir_build/src/thir/cx/expr.rs | 20 +- compiler/rustc_parse/src/parser/item.rs | 4 +- .../feature-gates/feature-gate-unnamed_fields.rs | 29 - .../feature-gate-unnamed_fields.stderr | 63 - .../anon-struct-in-enum-issue-121446.rs | 11 - .../anon-struct-in-enum-issue-121446.stderr | 16 - tests/ui/union/unnamed-fields/auxiliary/dep.rs | 18 - .../union/unnamed-fields/field_uniqueness_check.rs | 337 ---- .../unnamed-fields/field_uniqueness_check.stderr | 1734 -------------------- tests/ui/union/unnamed-fields/repr_check.rs | 69 - tests/ui/union/unnamed-fields/repr_check.stderr | 152 -- .../unnamed-fields/restrict_anonymous_structs.rs | 32 - .../restrict_anonymous_structs.stderr | 48 - .../unnamed-fields/restrict_anonymous_unions.rs | 32 - .../restrict_anonymous_unions.stderr | 48 - tests/ui/union/unnamed-fields/restrict_type_hir.rs | 44 - .../union/unnamed-fields/restrict_type_hir.stderr | 62 - .../unnamed-enum-field-issue-121757.rs | 25 - .../unnamed-enum-field-issue-121757.stderr | 45 - tests/ui/unpretty/expanded-exhaustive.rs | 14 - tests/ui/unpretty/expanded-exhaustive.stdout | 18 - 40 files changed, 30 insertions(+), 3209 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-unnamed_fields.rs delete mode 100644 tests/ui/feature-gates/feature-gate-unnamed_fields.stderr delete mode 100644 tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs delete mode 100644 tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr delete mode 100644 tests/ui/union/unnamed-fields/auxiliary/dep.rs delete mode 100644 tests/ui/union/unnamed-fields/field_uniqueness_check.rs delete mode 100644 tests/ui/union/unnamed-fields/field_uniqueness_check.stderr delete mode 100644 tests/ui/union/unnamed-fields/repr_check.rs delete mode 100644 tests/ui/union/unnamed-fields/repr_check.stderr delete mode 100644 tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs delete mode 100644 tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr delete mode 100644 tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs delete mode 100644 tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr delete mode 100644 tests/ui/union/unnamed-fields/restrict_type_hir.rs delete mode 100644 tests/ui/union/unnamed-fields/restrict_type_hir.stderr delete mode 100644 tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs delete mode 100644 tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index c361c35b723..0146a8d9082 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -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 diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 229d04f8de2..b3d91d881c4 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -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) } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 5cce47ce7bd..07515897c69 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -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 { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 83931a8c1a9..e47f5d43128 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -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"); diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 0cd0963d4e3..276814dd0d9 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -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), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index c5530097e96..843610a18a1 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -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() {`. (incomplete, unsized_const_params, "1.82.0", Some(95174)), diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index c73826c489f..b64a400f75e 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -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 diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d725772a5b3..b9111a5cd39 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -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::>(); - 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. diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 93b021be245..cfa148d925d 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -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 { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 4edb68e6199..9099703e812 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -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, - #[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 { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b34ed4640db..ed7be72551b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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; } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 62107877283..cd4c5de2a66 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -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))] diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 49c5a7d8a65..fb78da0a86c 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -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) }) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 3254dddaee9..b193b81f6de 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -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")] diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2157324d5cc..600a9b75097 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -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, ) } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 8f89f5c25af..3322a2643d7 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -259,12 +259,8 @@ impl AdtDefData { kind: AdtKind, variants: IndexVec, 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 } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2ffb273cb6f..4eaba540e33 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1419,16 +1419,8 @@ impl<'tcx> TyCtxt<'tcx> { kind: AdtKind, variants: IndexVec, 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`. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2b1212a5eb5..33bb5fa5739 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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, 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)] diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 17280c3d047..c01d2120111 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -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, - /// 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, 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 } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 2ffad0b4834..044d8045a27 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -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(); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9fc82d84225..13681c00f8e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -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 = diff --git a/tests/ui/feature-gates/feature-gate-unnamed_fields.rs b/tests/ui/feature-gates/feature-gate-unnamed_fields.rs deleted file mode 100644 index 302a9bbeb45..00000000000 --- a/tests/ui/feature-gates/feature-gate-unnamed_fields.rs +++ /dev/null @@ -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(){} diff --git a/tests/ui/feature-gates/feature-gate-unnamed_fields.stderr b/tests/ui/feature-gates/feature-gate-unnamed_fields.stderr deleted file mode 100644 index bc9e95bab98..00000000000 --- a/tests/ui/feature-gates/feature-gate-unnamed_fields.stderr +++ /dev/null @@ -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 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 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 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 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 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`. diff --git a/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs b/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs deleted file mode 100644 index 00f9bfd5cdf..00000000000 --- a/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs +++ /dev/null @@ -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 - } -} diff --git a/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr b/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr deleted file mode 100644 index 43843141e2e..00000000000 --- a/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/union/unnamed-fields/auxiliary/dep.rs b/tests/ui/union/unnamed-fields/auxiliary/dep.rs deleted file mode 100644 index a11f3e18f52..00000000000 --- a/tests/ui/union/unnamed-fields/auxiliary/dep.rs +++ /dev/null @@ -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; diff --git a/tests/ui/union/unnamed-fields/field_uniqueness_check.rs b/tests/ui/union/unnamed-fields/field_uniqueness_check.rs deleted file mode 100644 index ddb951aa06c..00000000000 --- a/tests/ui/union/unnamed-fields/field_uniqueness_check.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/union/unnamed-fields/field_uniqueness_check.stderr b/tests/ui/union/unnamed-fields/field_uniqueness_check.stderr deleted file mode 100644 index 11978386843..00000000000 --- a/tests/ui/union/unnamed-fields/field_uniqueness_check.stderr +++ /dev/null @@ -1,1734 +0,0 @@ -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:27:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:30:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:31:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:36:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:40:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:40:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:41:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:41:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:44:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:44:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:45:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:45:9 - | -LL | _: Bar, - | ^^^^^^ - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:58:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:61:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:66:17 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:70:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:70:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:71:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:71:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:74:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:74:13 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:75:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:75:13 - | -LL | _: Bar, - | ^^^^^^ - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:80:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:83:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:88:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:92:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:92:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:93:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:93:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:96:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:96:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:97:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:97:9 - | -LL | _: Bar, - | ^^^^^^ - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:111:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:114:17 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:119:21 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:123:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:123:13 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:124:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:124:13 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:127:17 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:127:17 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:128:17 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:128:17 - | -LL | _: Bar, - | ^^^^^^ - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:133:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:136:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:141:17 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:145:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:145:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:146:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:146:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:149:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:149:13 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:150:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:150:13 - | -LL | _: Bar, - | ^^^^^^ - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:154:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:157:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error[E0124]: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:162:13 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | a: u8, - | ^^^^^ field already declared - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:166:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:166:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:167:5 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:167:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:170:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:170:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:171:9 - | -LL | a: u8, - | ----- `a` first declared here -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:171:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:183:5 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:186:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:191:13 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:195:5 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:195:5 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:196:5 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:196:5 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:199:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:199:9 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:200:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:200:9 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:180:5 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:212:5 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:215:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:220:13 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:224:5 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:224:5 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:225:5 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:225:5 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:228:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:228:9 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:229:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:229:9 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:209:5 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:242:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:245:13 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:250:17 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:254:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:254:9 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:255:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:255:9 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:258:13 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:258:13 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:259:13 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:259:13 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:264:5 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:267:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:272:13 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:276:5 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:276:5 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:277:5 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:277:5 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:280:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:280:9 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:281:9 - | -LL | _: Foo, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:281:9 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:239:9 - | -LL | _: Foo, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:294:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:297:13 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:302:17 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:306:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:306:9 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:307:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:307:9 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:310:13 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:310:13 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:311:13 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:311:13 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:316:5 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:319:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:324:13 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | a: u8, - | ^^^^^ field already declared - | -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:328:5 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:328:5 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:329:5 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:329:5 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:332:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Foo, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:7:5 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:332:9 - | -LL | _: Foo, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: field `a` is already declared - --> $DIR/field_uniqueness_check.rs:333:9 - | -LL | _: Bar, - | ------ `a` first declared here in this unnamed field -... -LL | _: Bar, - | ^^^^^^ field `a` declared in this unnamed field - | -note: field `a` declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:333:9 - | -LL | _: Bar, - | ^^^^^^ -note: field `a` first declared here - --> $DIR/field_uniqueness_check.rs:14:9 - | -LL | a: u8, - | ^^^^^ -help: fields from the type of this unnamed field are considered fields of the outer type - --> $DIR/field_uniqueness_check.rs:291:9 - | -LL | _: Bar, - | ^^^^^^ - -error: aborting due to 85 previous errors - -For more information about this error, try `rustc --explain E0124`. diff --git a/tests/ui/union/unnamed-fields/repr_check.rs b/tests/ui/union/unnamed-fields/repr_check.rs deleted file mode 100644 index b50b54b20af..00000000000 --- a/tests/ui/union/unnamed-fields/repr_check.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/union/unnamed-fields/repr_check.stderr b/tests/ui/union/unnamed-fields/repr_check.stderr deleted file mode 100644 index 324968b1264..00000000000 --- a/tests/ui/union/unnamed-fields/repr_check.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs b/tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs deleted file mode 100644 index 03545ed7b18..00000000000 --- a/tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr b/tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr deleted file mode 100644 index 3b3890af771..00000000000 --- a/tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs b/tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs deleted file mode 100644 index 9ffe71b28c2..00000000000 --- a/tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr b/tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr deleted file mode 100644 index f8679aad2d7..00000000000 --- a/tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/union/unnamed-fields/restrict_type_hir.rs b/tests/ui/union/unnamed-fields/restrict_type_hir.rs deleted file mode 100644 index 80e4608be82..00000000000 --- a/tests/ui/union/unnamed-fields/restrict_type_hir.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/union/unnamed-fields/restrict_type_hir.stderr b/tests/ui/union/unnamed-fields/restrict_type_hir.stderr deleted file mode 100644 index 3e80d7fbf5c..00000000000 --- a/tests/ui/union/unnamed-fields/restrict_type_hir.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs b/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs deleted file mode 100644 index 5d15ec4cffd..00000000000 --- a/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr b/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr deleted file mode 100644 index 4ea910202de..00000000000 --- a/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr +++ /dev/null @@ -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 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`. diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs index 279d723a26c..b287e48e476 100644 --- a/tests/ui/unpretty/expanded-exhaustive.rs +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -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; diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 149659693ae..f8d09650d92 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -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; -- cgit 1.4.1-3-g733a5 From 40465d2449f3d9a36c86b94885f58ed3ee2a99f0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 22:17:30 -0400 Subject: Remove anon struct and union types --- compiler/rustc_ast/src/ast.rs | 8 ---- compiler/rustc_ast/src/mut_visit.rs | 4 -- compiler/rustc_ast/src/util/classify.rs | 6 --- compiler/rustc_ast/src/visit.rs | 3 -- compiler/rustc_ast_lowering/src/lib.rs | 40 ------------------ compiler/rustc_ast_passes/messages.ftl | 4 -- compiler/rustc_ast_passes/src/ast_validation.rs | 17 -------- compiler/rustc_ast_passes/src/errors.rs | 9 ----- compiler/rustc_ast_pretty/src/pprust/state.rs | 8 ---- .../rustc_builtin_macros/src/deriving/clone.rs | 2 +- compiler/rustc_builtin_macros/src/deriving/mod.rs | 2 - compiler/rustc_feature/src/removed.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 47 ---------------------- compiler/rustc_passes/src/hir_stats.rs | 2 - compiler/rustc_resolve/src/build_reduced_graph.rs | 23 ----------- compiler/rustc_resolve/src/def_collector.rs | 18 --------- src/tools/rustfmt/src/types.rs | 2 - src/tools/rustfmt/tests/target/anonymous-types.rs | 31 -------------- 19 files changed, 3 insertions(+), 227 deletions(-) delete mode 100644 src/tools/rustfmt/tests/target/anonymous-types.rs (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 37f429cce44..4a92cc881fa 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2167,10 +2167,6 @@ pub enum TyKind { Never, /// A tuple (`(A, B, C, D,...)`). Tup(ThinVec>), - /// An anonymous struct type i.e. `struct { foo: Type }`. - AnonStruct(NodeId, ThinVec), - /// An anonymous union type i.e. `union { bar: Type }`. - AnonUnion(NodeId, ThinVec), /// A path (`module::module::...::Type`), optionally /// "qualified", e.g., ` as SomeTrait>::SomeType`. /// @@ -2227,10 +2223,6 @@ impl TyKind { None } } - - pub fn is_anon_adt(&self) -> bool { - matches!(self, TyKind::AnonStruct(..) | TyKind::AnonUnion(..)) - } } /// Syntax used to declare a trait object. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 104f84f26e0..a59eed4125c 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -519,10 +519,6 @@ pub fn walk_ty(vis: &mut T, ty: &mut P) { visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Impl)); } TyKind::MacCall(mac) => vis.visit_mac_call(mac), - TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => { - vis.visit_id(id); - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } } visit_lazy_tts(vis, tokens); vis.visit_span(span); diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 1a80a9ccdbf..a517f17c82c 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -287,12 +287,6 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { | ast::TyKind::Pat(..) | ast::TyKind::Dummy | ast::TyKind::Err(..) => break None, - - // These end in brace, but cannot occur in a let-else statement. - // They are only parsed as fields of a data structure. For the - // purpose of denying trailing braces in the expression of a - // let-else, we can disregard these. - ast::TyKind::AnonStruct(..) | ast::TyKind::AnonUnion(..) => break None, } } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9f9c3d8c392..4dcadb8517e 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -535,9 +535,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { TyKind::Err(_guar) => {} TyKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), TyKind::Never | TyKind::CVarArgs => {} - TyKind::AnonStruct(_id, ref fields) | TyKind::AnonUnion(_id, ref fields) => { - walk_list!(visitor, visit_field_def, fields); - } } V::Result::output() } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c6cb7aa7dd5..e38374281f7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1264,46 +1264,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err(guar) => hir::TyKind::Err(*guar), - // Lower the anonymous structs or unions in a nested lowering context. - // - // ``` - // struct Foo { - // _: union { - // // ^__________________ <-- within the nested lowering context, - // /* fields */ // | we lower all fields defined into an - // } // | owner node of struct or union item - // // ^_____________________| - // } - // ``` - TyKind::AnonStruct(node_id, fields) | TyKind::AnonUnion(node_id, fields) => { - // Here its `def_id` is created in `build_reduced_graph`. - let def_id = self.local_def_id(*node_id); - debug!(?def_id); - let owner_id = hir::OwnerId { def_id }; - self.with_hir_id_owner(*node_id, |this| { - let fields = this.arena.alloc_from_iter( - fields.iter().enumerate().map(|f| this.lower_field_def(f)), - ); - let span = t.span; - let variant_data = - hir::VariantData::Struct { fields, recovered: ast::Recovered::No }; - // FIXME: capture the generics from the outer adt. - let generics = hir::Generics::empty(); - let kind = match t.kind { - TyKind::AnonStruct(..) => hir::ItemKind::Struct(variant_data, generics), - TyKind::AnonUnion(..) => hir::ItemKind::Union(variant_data, generics), - _ => unreachable!(), - }; - hir::OwnerNode::Item(this.arena.alloc(hir::Item { - ident: Ident::new(kw::Empty, span), - owner_id, - kind, - span: this.lower_span(span), - vis_span: this.lower_span(span.shrink_to_lo()), - })) - }); - hir::TyKind::AnonAdt(hir::ItemId { owner_id }) - } TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Ref(region, mt) => { diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 0146a8d9082..7cfbd6c6c6c 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -1,7 +1,3 @@ -ast_passes_anon_struct_or_union_not_allowed = - anonymous {$struct_or_union}s are not allowed outside of unnamed struct or union fields - .label = anonymous {$struct_or_union} declared here - ast_passes_assoc_const_without_body = associated constant in `impl` without body .suggestion = provide a definition for the constant diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index b3d91d881c4..f99654a9a65 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -244,9 +244,6 @@ impl<'a> AstValidator<'a> { } } } - TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => { - walk_list!(self, visit_struct_field_def, fields) - } _ => visit::walk_ty(self, t), } } @@ -293,15 +290,6 @@ impl<'a> AstValidator<'a> { } } - fn deny_anon_struct_or_union(&self, ty: &Ty) { - let struct_or_union = match &ty.kind { - TyKind::AnonStruct(..) => "struct", - TyKind::AnonUnion(..) => "union", - _ => return, - }; - self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span }); - } - fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) { let Const::Yes(span) = constness else { return; @@ -865,14 +853,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_ty(&mut self, ty: &'a Ty) { self.visit_ty_common(ty); - self.deny_anon_struct_or_union(ty); self.walk_ty(ty) } - fn visit_field_def(&mut self, field: &'a FieldDef) { - visit::walk_field_def(self, field) - } - fn visit_item(&mut self, item: &'a Item) { if item.attrs.iter().any(|attr| attr.is_proc_macro_attr()) { self.has_proc_macro_decls = true; diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 07515897c69..c60925b3049 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -814,15 +814,6 @@ pub(crate) struct NegativeBoundWithParentheticalNotation { pub span: Span, } -#[derive(Diagnostic)] -#[diag(ast_passes_anon_struct_or_union_not_allowed)] -pub(crate) struct AnonStructOrUnionNotAllowed { - #[primary_span] - #[label] - pub span: Span, - pub struct_or_union: &'static str, -} - #[derive(Diagnostic)] #[diag(ast_passes_match_arm_with_no_body)] pub(crate) struct MatchArmWithNoBody { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 7e07ccf28a0..01713a9beca 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1174,14 +1174,6 @@ impl<'a> State<'a> { } self.pclose(); } - ast::TyKind::AnonStruct(_, fields) => { - self.head("struct"); - self.print_record_struct_body(fields, ty.span); - } - ast::TyKind::AnonUnion(_, fields) => { - self.head("union"); - self.print_record_struct_body(fields, ty.span); - } ast::TyKind::Paren(typ) => { self.popen(); self.print_type(typ); diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index dde696fca61..f79227d52a8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -113,7 +113,7 @@ fn cs_clone_simple( // Already produced an assertion for this type. // Anonymous structs or unions must be eliminated as they cannot be // type parameters. - } else if !field.ty.kind.is_anon_adt() { + } else { // let _: AssertParamIsClone; super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[ sym::clone, diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index d5ee5e430d5..e884c0ec718 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -124,8 +124,6 @@ fn assert_ty_bounds( span: Span, assert_path: &[Symbol], ) { - // Deny anonymous structs or unions to avoid weird errors. - assert!(!ty.kind.is_anon_adt(), "Anonymous structs or unions cannot be type parameters"); // Generate statement `let _: assert_path;`. let span = cx.with_def_site_ctxt(span); let assert_path = cx.path_all(span, true, cx.std_path(assert_path), vec![GenericArg::Type(ty)]); diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 276814dd0d9..85bc1460b3e 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -217,7 +217,7 @@ declare_features! ( /// 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, unnamed_fields, "CURRENT_RUSTC_VERSION", Some(49804), Some("feature needs redesign")), (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), diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 13681c00f8e..36733726564 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1984,7 +1984,7 @@ impl<'a> Parser<'a> { } } self.expect_field_ty_separator()?; - let ty = self.parse_ty_for_field_def()?; + let ty = self.parse_ty()?; if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) { self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span }); } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a8ed8b5df9c..625a4cabdf2 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -128,17 +128,6 @@ impl<'a> Parser<'a> { ) } - /// Parse a type suitable for a field definition. - /// The difference from `parse_ty` is that this version - /// allows anonymous structs and unions. - pub(super) fn parse_ty_for_field_def(&mut self) -> PResult<'a, P> { - if self.can_begin_anon_struct_or_union() { - self.parse_anon_struct_or_union() - } else { - self.parse_ty() - } - } - /// Parse a type suitable for a function or function pointer parameter. /// The difference from `parse_ty` is that this version allows `...` /// (`CVarArgs`) at the top level of the type. @@ -382,37 +371,6 @@ impl<'a> Parser<'a> { if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) } } - /// Parse an anonymous struct or union (only for field definitions): - /// ```ignore (feature-not-ready) - /// #[repr(C)] - /// struct Foo { - /// _: struct { // anonymous struct - /// x: u32, - /// y: f64, - /// } - /// _: union { // anonymous union - /// z: u32, - /// w: f64, - /// } - /// } - /// ``` - fn parse_anon_struct_or_union(&mut self) -> PResult<'a, P> { - assert!(self.token.is_keyword(kw::Union) || self.token.is_keyword(kw::Struct)); - let is_union = self.token.is_keyword(kw::Union); - - let lo = self.token.span; - self.bump(); - - let (fields, _recovered) = - self.parse_record_struct_body(if is_union { "union" } else { "struct" }, lo, false)?; - let span = lo.to(self.prev_token.span); - self.psess.gated_spans.gate(sym::unnamed_fields, span); - let id = ast::DUMMY_NODE_ID; - let kind = - if is_union { TyKind::AnonUnion(id, fields) } else { TyKind::AnonStruct(id, fields) }; - Ok(self.mk_ty(span, kind)) - } - /// Parses either: /// - `(TYPE)`, a parenthesized type. /// - `(TYPE,)`, a tuple with a single field of type TYPE. @@ -813,11 +771,6 @@ impl<'a> Parser<'a> { Ok(bounds) } - pub(super) fn can_begin_anon_struct_or_union(&mut self) -> bool { - (self.token.is_keyword(kw::Struct) || self.token.is_keyword(kw::Union)) - && self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)) - } - /// Can the current token begin a bound? fn can_begin_bound(&mut self) -> bool { self.check_path() diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 903fb114744..e89838b22ab 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -583,8 +583,6 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { BareFn, Never, Tup, - AnonStruct, - AnonUnion, Path, Pat, TraitObject, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index a9ea268e51a..ae7389342ec 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -724,29 +724,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // Record field names for error reporting. self.insert_field_idents(def_id, fields); self.insert_field_visibilities_local(def_id.to_def_id(), fields); - - for field in fields { - match &field.ty.kind { - ast::TyKind::AnonStruct(id, nested_fields) - | ast::TyKind::AnonUnion(id, nested_fields) => { - let feed = self.r.feed(*id); - let local_def_id = feed.key(); - let def_id = local_def_id.to_def_id(); - let def_kind = self.r.tcx.def_kind(local_def_id); - let res = Res::Def(def_kind, def_id); - self.build_reduced_graph_for_struct_variant( - &nested_fields, - Ident::empty(), - feed, - res, - // Anonymous adts inherit visibility from their parent adts. - adt_vis, - field.ty.span, - ); - } - _ => {} - } - } } /// Constructs the reduced graph for one item. diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 98662385434..0047f2c4b51 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -105,22 +105,6 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); let def = self.create_def(field.id, name, DefKind::Field, field.span); self.with_parent(def, |this| visit::walk_field_def(this, field)); - self.visit_anon_adt(&field.ty); - } - } - - fn visit_anon_adt(&mut self, ty: &'a Ty) { - let def_kind = match &ty.kind { - TyKind::AnonStruct(..) => DefKind::Struct, - TyKind::AnonUnion(..) => DefKind::Union, - _ => return, - }; - match &ty.kind { - TyKind::AnonStruct(node_id, _) | TyKind::AnonUnion(node_id, _) => { - let def_id = self.create_def(*node_id, kw::Empty, def_kind, ty.span); - self.with_parent(def_id, |this| visit::walk_ty(this, ty)); - } - _ => {} } } @@ -476,8 +460,6 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { fn visit_ty(&mut self, ty: &'a Ty) { match &ty.kind { TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), - // Anonymous structs or unions are visited later after defined. - TyKind::AnonStruct(..) | TyKind::AnonUnion(..) => {} TyKind::ImplTrait(id, _) => { // HACK: pprust breaks strings with newlines when the type // gets too long. We don't want these to show up in compiler diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 07b483b2b37..f75c4f0fad7 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -951,8 +951,6 @@ impl Rewrite for ast::Ty { ast::TyKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1) } - ast::TyKind::AnonStruct(..) => Ok(context.snippet(self.span).to_owned()), - ast::TyKind::AnonUnion(..) => Ok(context.snippet(self.span).to_owned()), ast::TyKind::Path(ref q_self, ref path) => { rewrite_path(context, PathContext::Type, q_self, path, shape) } diff --git a/src/tools/rustfmt/tests/target/anonymous-types.rs b/src/tools/rustfmt/tests/target/anonymous-types.rs deleted file mode 100644 index e8c2d83878c..00000000000 --- a/src/tools/rustfmt/tests/target/anonymous-types.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Test for issue 85480 -// Pretty print anonymous struct and union types - -// pp-exact -// pretty-compare-only - -struct Foo { - _: union { - _: struct { - a: u8, - b: u16, - }, - c: u32, - }, - d: u64, - e: f32, -} - -// Test for https://github.com/rust-lang/rust/issues/117942 -struct Foo { - _: union { - #[rustfmt::skip] - f: String, - }, - #[rustfmt::skip] - _: struct { - g: i32, - }, -} - -fn main() {} -- cgit 1.4.1-3-g733a5 From ae698f819935aae8623f41aa3837cc0a07903c1a Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 Sep 2024 12:09:18 -0700 Subject: Add sugar for &pin (const|mut) types --- compiler/rustc_ast/src/ast.rs | 11 ++++- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/util/classify.rs | 4 +- compiler/rustc_ast/src/visit.rs | 3 +- compiler/rustc_ast_ir/src/lib.rs | 7 +++ compiler/rustc_ast_lowering/src/expr.rs | 5 ++- compiler/rustc_ast_lowering/src/lib.rs | 51 ++++++++++++++++++---- .../rustc_ast_lowering/src/lifetime_collector.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_ast_pretty/src/pprust/state.rs | 6 +++ compiler/rustc_hir/src/hir.rs | 5 +-- compiler/rustc_parse/src/parser/ty.rs | 39 ++++++++++++++--- compiler/rustc_passes/src/hir_stats.rs | 50 +++++++++++---------- compiler/rustc_resolve/src/late.rs | 4 +- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 3 ++ src/tools/rustfmt/src/types.rs | 5 ++- tests/ui/async-await/pin-sugar-ambiguity.rs | 15 +++++++ tests/ui/async-await/pin-sugar-no-const.rs | 8 ++++ tests/ui/async-await/pin-sugar-no-const.stderr | 15 +++++++ tests/ui/async-await/pin-sugar.rs | 51 ++++++++++++++++++++++ .../feature-gates/feature-gate-pin_ergonomics.rs | 11 +++-- .../feature-gate-pin_ergonomics.stderr | 45 ++++++++++++++++--- 23 files changed, 283 insertions(+), 62 deletions(-) create mode 100644 tests/ui/async-await/pin-sugar-ambiguity.rs create mode 100644 tests/ui/async-await/pin-sugar-no-const.rs create mode 100644 tests/ui/async-await/pin-sugar-no-const.stderr create mode 100644 tests/ui/async-await/pin-sugar.rs (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f2b52eea12f..88db97b66e4 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -23,7 +23,7 @@ use std::{cmp, fmt, mem}; pub use GenericArgs::*; pub use UnsafeSource::*; -pub use rustc_ast_ir::{Movability, Mutability}; +pub use rustc_ast_ir::{Movability, Mutability, Pinnedness}; use rustc_data_structures::packed::Pu128; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -2161,6 +2161,10 @@ pub enum TyKind { Ptr(MutTy), /// A reference (`&'a T` or `&'a mut T`). Ref(Option, MutTy), + /// A pinned reference (`&'a pin const T` or `&'a pin mut T`). + /// + /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`. + PinnedRef(Option, MutTy), /// A bare function (e.g., `fn(usize) -> bool`). BareFn(P), /// The never type (`!`). @@ -2509,7 +2513,10 @@ impl Param { if ident.name == kw::SelfLower { return match self.ty.kind { TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), - TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { + TyKind::Ref(lt, MutTy { ref ty, mutbl }) + | TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }) + if ty.kind.is_implicit_self() => + { Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) } _ => Some(respan( diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 6ce23a1479d..1c57dd948fc 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -485,7 +485,7 @@ pub fn walk_ty(vis: &mut T, ty: &mut P) { } TyKind::Slice(ty) => vis.visit_ty(ty), TyKind::Ptr(mt) => vis.visit_mt(mt), - TyKind::Ref(lt, mt) => { + TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => { visit_opt(lt, |lt| vis.visit_lifetime(lt)); vis.visit_mt(mt); } diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 1a80a9ccdbf..8fdaf995850 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -247,7 +247,9 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { break (mac.args.delim == Delimiter::Brace).then_some(mac); } - ast::TyKind::Ptr(mut_ty) | ast::TyKind::Ref(_, mut_ty) => { + ast::TyKind::Ptr(mut_ty) + | ast::TyKind::Ref(_, mut_ty) + | ast::TyKind::PinnedRef(_, mut_ty) => { ty = &mut_ty.ty; } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9f9c3d8c392..1ab88e8c02e 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -499,7 +499,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { match kind { TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)), TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)), - TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) => { + TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) + | TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => { visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref); try_visit!(visitor.visit_ty(ty)); } diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index eeed5d36151..ff9d940ce9f 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -79,3 +79,10 @@ impl Mutability { matches!(self, Self::Not) } } + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] +pub enum Pinnedness { + Not, + Pinned, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 52372bbf991..ae1e1b3f8a2 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -640,7 +640,8 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_span(span), Some(self.allow_gen_future.clone()), ); - let resume_ty = self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span); + let resume_ty = + self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None); let input_ty = hir::Ty { hir_id: self.next_id(), kind: hir::TyKind::Path(resume_ty), @@ -2065,7 +2066,7 @@ impl<'hir> LoweringContext<'_, 'hir> { lang_item: hir::LangItem, name: Symbol, ) -> hir::Expr<'hir> { - let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span)); + let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span), None); let path = hir::ExprKind::Path(hir::QPath::TypeRelative( self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))), self.arena.alloc(hir::PathSegment::new( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b26797f4203..bd20a70f325 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -55,8 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::{ - self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName, - TraitCandidate, + self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, MissingLifetimeKind, + ParamName, TraitCandidate, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -765,8 +765,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { res } - fn make_lang_item_qpath(&mut self, lang_item: hir::LangItem, span: Span) -> hir::QPath<'hir> { - hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, None)) + fn make_lang_item_qpath( + &mut self, + lang_item: hir::LangItem, + span: Span, + args: Option<&'hir hir::GenericArgs<'hir>>, + ) -> hir::QPath<'hir> { + hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args)) } fn make_lang_item_path( @@ -1317,6 +1322,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetime = self.lower_lifetime(®ion); hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx)) } + TyKind::PinnedRef(region, mt) => { + let region = region.unwrap_or_else(|| { + let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = + self.resolver.get_lifetime_res(t.id) + { + debug_assert_eq!(start.plus(1), end); + start + } else { + self.next_node_id() + }; + let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi(); + Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } + }); + let lifetime = self.lower_lifetime(®ion); + let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx)); + let span = self.lower_span(t.span); + let arg = hir::Ty { kind, span, hir_id: self.next_id() }; + let args = self.arena.alloc(hir::GenericArgs { + args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]), + constraints: &[], + parenthesized: hir::GenericArgsParentheses::No, + span_ext: span, + }); + let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args)); + hir::TyKind::Path(path) + } TyKind::BareFn(f) => { let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { @@ -1882,10 +1913,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Given we are only considering `ImplicitSelf` types, we needn't consider // the case where we have a mutable pattern to a reference as that would // no longer be an `ImplicitSelf`. - TyKind::Ref(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl { - hir::Mutability::Not => hir::ImplicitSelfKind::RefImm, - hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut, - }, + TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt) + if mt.ty.kind.is_implicit_self() => + { + match mt.mutbl { + hir::Mutability::Not => hir::ImplicitSelfKind::RefImm, + hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut, + } + } _ => hir::ImplicitSelfKind::None, } }), diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 1e82ba5db8a..fe64160fb4d 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -95,7 +95,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { visit::walk_ty(self, t); self.current_binders.pop(); } - TyKind::Ref(None, _) => { + TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => { self.record_elided_anchor(t.id, t.span); visit::walk_ty(self, t); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 42d1ef5c558..5daaa840e13 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -547,6 +547,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(mut_ref, "mutable by-reference bindings are experimental"); gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); + gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 884cc413bd5..8b3653ab097 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1163,6 +1163,12 @@ impl<'a> State<'a> { self.print_opt_lifetime(lifetime); self.print_mt(mt, false); } + ast::TyKind::PinnedRef(lifetime, mt) => { + self.word("&"); + self.print_opt_lifetime(lifetime); + self.word("pin "); + self.print_mt(mt, true); + } ast::TyKind::Never => { self.word("!"); } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2ef6fa53f4e..bc5ed249559 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,10 +1,9 @@ use std::fmt; -use rustc_ast as ast; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{ - Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitKind, - TraitObjectSyntax, UintTy, + self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, + LitKind, TraitObjectSyntax, UintTy, }; pub use rustc_ast::{ BinOp, BinOpKind, BindingMode, BorrowKind, ByRef, CaptureBy, ImplPolarity, IsAuto, Movability, diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a8ed8b5df9c..ccd6dfda797 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,9 +2,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, - GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, - PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, + self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{Ident, kw, sym}; @@ -529,7 +527,10 @@ impl<'a> Parser<'a> { fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { let and_span = self.prev_token.span; let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime()); - let mut mutbl = self.parse_mutability(); + let (pinned, mut mutbl) = match self.parse_pin_and_mut() { + Some(pin_mut) => pin_mut, + None => (Pinnedness::Not, self.parse_mutability()), + }; if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { // A lifetime is invalid here: it would be part of a bare trait bound, which requires // it to be followed by a plus, but we disallow plus in the pointee type. @@ -565,7 +566,35 @@ impl<'a> Parser<'a> { self.bump_with((dyn_tok, dyn_tok_sp)); } let ty = self.parse_ty_no_plus()?; - Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl })) + Ok(match pinned { + Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }), + Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }), + }) + } + + /// Parses `pin` and `mut` annotations on references. + /// + /// It must be either `pin const` or `pin mut`. + pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> { + if self.token.is_ident_named(sym::pin) { + let result = self.look_ahead(1, |token| { + if token.is_keyword(kw::Const) { + Some((Pinnedness::Pinned, Mutability::Not)) + } else if token.is_keyword(kw::Mut) { + Some((Pinnedness::Pinned, Mutability::Mut)) + } else { + None + } + }); + if result.is_some() { + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); + self.bump(); + } + result + } else { + None + } } // Parses the `typeof(EXPR)`. diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 8ad14b6eb74..fc9d548d1fb 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -574,29 +574,33 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { } fn visit_ty(&mut self, t: &'v ast::Ty) { - record_variants!((self, t, t.kind, Id::None, ast, Ty, TyKind), [ - Slice, - Array, - Ptr, - Ref, - BareFn, - Never, - Tup, - AnonStruct, - AnonUnion, - Path, - Pat, - TraitObject, - ImplTrait, - Paren, - Typeof, - Infer, - ImplicitSelf, - MacCall, - CVarArgs, - Dummy, - Err - ]); + record_variants!( + (self, t, t.kind, Id::None, ast, Ty, TyKind), + [ + Slice, + Array, + Ptr, + Ref, + PinnedRef, + BareFn, + Never, + Tup, + AnonStruct, + AnonUnion, + Path, + Pat, + TraitObject, + ImplTrait, + Paren, + Typeof, + Infer, + ImplicitSelf, + MacCall, + CVarArgs, + Dummy, + Err + ] + ); ast_visit::walk_ty(self, t) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 66c1ff93ce1..b84cbf9c629 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -779,7 +779,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r let prev = self.diag_metadata.current_trait_object; let prev_ty = self.diag_metadata.current_type_path; match &ty.kind { - TyKind::Ref(None, _) => { + TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => { // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with // NodeId `ty.id`. // This span will be used in case of elision failure. @@ -2326,7 +2326,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &'ra Ty) { trace!("FindReferenceVisitor considering ty={:?}", ty); - if let TyKind::Ref(lt, _) = ty.kind { + if let TyKind::Ref(lt, _) | TyKind::PinnedRef(lt, _) = ty.kind { // See if anything inside the &thing contains Self let mut visitor = SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false }; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index fce5ec36c66..aced05ca351 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3482,7 +3482,7 @@ struct LifetimeFinder<'ast> { impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> { fn visit_ty(&mut self, t: &'ast Ty) { - if let TyKind::Ref(_, mut_ty) = &t.kind { + if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind { self.seen.push(t); if t.span.lo() == self.lifetime.lo() { self.found = Some(&mut_ty.ty); diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 68f74e52ed7..187f7fb4417 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -753,6 +753,9 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (Ref(ll, l), Ref(rl, r)) => { both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) }, + (PinnedRef(ll, l), PinnedRef(rl, r)) => { + both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) + }, (BareFn(l), BareFn(r)) => { l.safety == r.safety && eq_ext(&l.ext, &r.ext) diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 07b483b2b37..b64e069e096 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -827,7 +827,8 @@ impl Rewrite for ast::Ty { rewrite_unary_prefix(context, prefix, &*mt.ty, shape) } - ast::TyKind::Ref(ref lifetime, ref mt) => { + ast::TyKind::Ref(ref lifetime, _pinned, ref mt) => { + // FIXME: format pinnedness let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); @@ -1262,7 +1263,7 @@ pub(crate) fn can_be_overflowed_type( ) -> bool { match ty.kind { ast::TyKind::Tup(..) => context.use_block_indent() && len == 1, - ast::TyKind::Ref(_, ref mutty) | ast::TyKind::Ptr(ref mutty) => { + ast::TyKind::Ref(_, _, ref mutty) | ast::TyKind::Ptr(ref mutty) => { can_be_overflowed_type(context, &*mutty.ty, len) } _ => false, diff --git a/tests/ui/async-await/pin-sugar-ambiguity.rs b/tests/ui/async-await/pin-sugar-ambiguity.rs new file mode 100644 index 00000000000..d183000931e --- /dev/null +++ b/tests/ui/async-await/pin-sugar-ambiguity.rs @@ -0,0 +1,15 @@ +//@ check-pass +#![feature(pin_ergonomics)] +#![allow(dead_code, incomplete_features)] + +// Handle the case where there's ambiguity between pin as a contextual keyword and pin as a path. + +struct Foo; + +mod pin { + pub struct Foo; +} + +fn main() { + let _x: &pin ::Foo = &pin::Foo; +} diff --git a/tests/ui/async-await/pin-sugar-no-const.rs b/tests/ui/async-await/pin-sugar-no-const.rs new file mode 100644 index 00000000000..dd6456b6034 --- /dev/null +++ b/tests/ui/async-await/pin-sugar-no-const.rs @@ -0,0 +1,8 @@ +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] + +// Makes sure we don't accidentally accept `&pin Foo` without the `const` keyword. + +fn main() { + let _x: &pin i32 = todo!(); //~ ERROR found `i32` +} diff --git a/tests/ui/async-await/pin-sugar-no-const.stderr b/tests/ui/async-await/pin-sugar-no-const.stderr new file mode 100644 index 00000000000..5f01156c1f0 --- /dev/null +++ b/tests/ui/async-await/pin-sugar-no-const.stderr @@ -0,0 +1,15 @@ +error: expected one of `!`, `(`, `::`, `;`, `<`, or `=`, found `i32` + --> $DIR/pin-sugar-no-const.rs:7:18 + | +LL | let _x: &pin i32 = todo!(); + | - ^^^ expected one of `!`, `(`, `::`, `;`, `<`, or `=` + | | + | while parsing the type for `_x` + | +help: there is a keyword `in` with a similar name + | +LL | let _x: &in i32 = todo!(); + | ~~ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/pin-sugar.rs b/tests/ui/async-await/pin-sugar.rs new file mode 100644 index 00000000000..8dbdec418b1 --- /dev/null +++ b/tests/ui/async-await/pin-sugar.rs @@ -0,0 +1,51 @@ +//@ check-pass + +#![feature(pin_ergonomics)] +#![allow(dead_code, incomplete_features)] + +// Makes sure we can handle `&pin mut T` and `&pin const T` as sugar for `Pin<&mut T>` and +// `Pin<&T>`. + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn baz(self: &pin mut Self) { + } + + fn baz_const(self: &pin const Self) { + } + + fn baz_lt<'a>(self: &'a pin mut Self) { + } + + fn baz_const_lt(self: &'_ pin const Self) { + } +} + +fn foo(_: &pin mut Foo) { +} + +fn foo_const(x: &pin const Foo) { +} + +fn bar(x: &pin mut Foo) { + foo(x); + foo(x); // for this to work we need to automatically reborrow, + // as if the user had written `foo(x.as_mut())`. + + Foo::baz(x); + Foo::baz(x); + + // make sure we can reborrow &mut as &. + foo_const(x); + Foo::baz_const(x); + + let x: &pin const _ = Pin::new(&Foo); + + foo_const(x); // make sure reborrowing from & to & works. + foo_const(x); +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 3382504af9d..4624faf1e53 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, incomplete_features)] +#![allow(dead_code)] use std::pin::Pin; @@ -9,10 +9,13 @@ impl Foo { } } -fn foo(_: Pin<&mut Foo>) { +fn foo(x: Pin<&mut Foo>) { + let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental } -fn bar(mut x: Pin<&mut Foo>) { +fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental + +fn bar(x: Pin<&mut Foo>) { foo(x); foo(x); //~ ERROR use of moved value: `x` } @@ -22,4 +25,6 @@ fn baz(mut x: Pin<&mut Foo>) { x.foo(); //~ ERROR use of moved value: `x` } +fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr index 430b7866241..dd93a7be1ad 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr @@ -1,8 +1,38 @@ +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:13:14 + | +LL | let _y: &pin mut Foo = x; + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:16:18 + | +LL | fn foo_sugar(_: &pin mut Foo) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:28:18 + | +LL | fn baz_sugar(_: &pin const Foo) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` 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[E0382]: use of moved value: `x` - --> $DIR/feature-gate-pin_ergonomics.rs:17:9 + --> $DIR/feature-gate-pin_ergonomics.rs:20:9 | -LL | fn bar(mut x: Pin<&mut Foo>) { - | ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait +LL | fn bar(x: Pin<&mut Foo>) { + | - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait LL | foo(x); | - value moved here LL | foo(x); @@ -11,13 +41,13 @@ LL | foo(x); note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary --> $DIR/feature-gate-pin_ergonomics.rs:12:11 | -LL | fn foo(_: Pin<&mut Foo>) { +LL | fn foo(x: Pin<&mut Foo>) { | --- ^^^^^^^^^^^^^ this parameter takes ownership of the value | | | in this function error[E0382]: use of moved value: `x` - --> $DIR/feature-gate-pin_ergonomics.rs:22:5 + --> $DIR/feature-gate-pin_ergonomics.rs:25:5 | LL | fn baz(mut x: Pin<&mut Foo>) { | ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait @@ -36,6 +66,7 @@ help: consider reborrowing the `Pin` instead of moving it LL | x.as_mut().foo(); | +++++++++ -error: aborting due to 2 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0382`. +Some errors have detailed explanations: E0382, E0658. +For more information about an error, try `rustc --explain E0382`. -- cgit 1.4.1-3-g733a5 From b490bf56b7da3a689f0ea7a46f56d7cd2339efb0 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 Sep 2024 15:44:43 -0700 Subject: Fix clippy and rustfmt compilation --- compiler/rustc_parse/src/parser/ty.rs | 5 +++- compiler/rustc_passes/src/hir_stats.rs | 51 ++++++++++++++++------------------ src/tools/rustfmt/src/types.rs | 11 ++++---- 3 files changed, 34 insertions(+), 33 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index ccd6dfda797..b0ff033cf80 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,7 +2,10 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID + self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, + GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, + Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, + TyKind, }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{Ident, kw, sym}; diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index fc9d548d1fb..daf1bd8b19d 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -574,33 +574,30 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { } fn visit_ty(&mut self, t: &'v ast::Ty) { - record_variants!( - (self, t, t.kind, Id::None, ast, Ty, TyKind), - [ - Slice, - Array, - Ptr, - Ref, - PinnedRef, - BareFn, - Never, - Tup, - AnonStruct, - AnonUnion, - Path, - Pat, - TraitObject, - ImplTrait, - Paren, - Typeof, - Infer, - ImplicitSelf, - MacCall, - CVarArgs, - Dummy, - Err - ] - ); + record_variants!((self, t, t.kind, Id::None, ast, Ty, TyKind), [ + Slice, + Array, + Ptr, + Ref, + PinnedRef, + BareFn, + Never, + Tup, + AnonStruct, + AnonUnion, + Path, + Pat, + TraitObject, + ImplTrait, + Paren, + Typeof, + Infer, + ImplicitSelf, + MacCall, + CVarArgs, + Dummy, + Err + ]); ast_visit::walk_ty(self, t) } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index b64e069e096..999deb5dd4a 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -827,8 +827,9 @@ impl Rewrite for ast::Ty { rewrite_unary_prefix(context, prefix, &*mt.ty, shape) } - ast::TyKind::Ref(ref lifetime, _pinned, ref mt) => { - // FIXME: format pinnedness + ast::TyKind::Ref(ref lifetime, ref mt) + | ast::TyKind::PinnedRef(ref lifetime, ref mt) => { + // FIXME(pin_ergonomics): correctly format pinned reference syntax let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); @@ -1263,9 +1264,9 @@ pub(crate) fn can_be_overflowed_type( ) -> bool { match ty.kind { ast::TyKind::Tup(..) => context.use_block_indent() && len == 1, - ast::TyKind::Ref(_, _, ref mutty) | ast::TyKind::Ptr(ref mutty) => { - can_be_overflowed_type(context, &*mutty.ty, len) - } + ast::TyKind::Ref(_, ref mutty) + | ast::TyKind::PinnedRef(_, ref mutty) + | ast::TyKind::Ptr(ref mutty) => can_be_overflowed_type(context, &*mutty.ty, len), _ => false, } } -- cgit 1.4.1-3-g733a5 From 95dba280b9e471fc2dce93195d3b6f4aeb31279c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 13 Oct 2024 09:31:22 -0400 Subject: Move trait bound modifiers into ast::PolyTraitRef --- compiler/rustc_ast/src/ast.rs | 21 +++++++--- compiler/rustc_ast/src/mut_visit.rs | 4 +- compiler/rustc_ast/src/util/classify.rs | 2 +- compiler/rustc_ast/src/visit.rs | 4 +- compiler/rustc_ast_lowering/src/item.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 15 +++---- compiler/rustc_ast_passes/src/ast_validation.rs | 16 +++++--- compiler/rustc_ast_pretty/src/pprust/state.rs | 48 ++++++++++------------ .../rustc_builtin_macros/src/deriving/smart_ptr.rs | 10 ++--- compiler/rustc_expand/src/build.rs | 21 +++++----- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_parse/src/parser/path.rs | 4 +- compiler/rustc_parse/src/parser/ty.rs | 14 +++++-- compiler/rustc_resolve/src/late/diagnostics.rs | 37 +++++++++-------- src/tools/clippy/clippy_utils/src/ast_utils.rs | 5 ++- src/tools/rustfmt/src/spanned.rs | 2 +- src/tools/rustfmt/src/types.rs | 12 +++--- 17 files changed, 118 insertions(+), 103 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 937031324f5..883391a2b60 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -308,7 +308,7 @@ impl TraitBoundModifiers { #[derive(Clone, Encodable, Decodable, Debug)] pub enum GenericBound { - Trait(PolyTraitRef, TraitBoundModifiers), + Trait(PolyTraitRef), Outlives(Lifetime), /// Precise capturing syntax: `impl Sized + use<'a>` Use(ThinVec, Span), @@ -1213,10 +1213,12 @@ impl Expr { pub fn to_bound(&self) -> Option { match &self.kind { - ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(ThinVec::new(), path.clone(), self.span), + ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new( + ThinVec::new(), + path.clone(), TraitBoundModifiers::NONE, - )), + self.span, + ))), _ => None, } } @@ -2965,6 +2967,9 @@ pub struct PolyTraitRef { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: ThinVec, + // Optional constness, asyncness, or polarity. + pub modifiers: TraitBoundModifiers, + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, @@ -2972,9 +2977,15 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new(generic_params: ThinVec, path: Path, span: Span) -> Self { + pub fn new( + generic_params: ThinVec, + path: Path, + modifiers: TraitBoundModifiers, + span: Span, + ) -> Self { PolyTraitRef { bound_generic_params: generic_params, + modifiers, trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, span, } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 1a7da46913d..b03c8aaa53b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -913,7 +913,7 @@ fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { match pb { - GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), + GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref), GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), GenericBound::Use(args, span) => { for arg in args { @@ -1034,7 +1034,7 @@ fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut Tr } fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, trait_ref, span } = p; + let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p; bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_trait_ref(trait_ref); vis.visit_span(span); diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index a517f17c82c..695ebd168ee 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -263,7 +263,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => { match bounds.last() { - Some(ast::GenericBound::Trait(bound, _)) => { + Some(ast::GenericBound::Trait(bound)) => { match path_return_type(&bound.trait_ref.path) { Some(trailing_ty) => ty = trailing_ty, None => break None, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 4dcadb8517e..6593d5dbb5c 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) where V: Visitor<'a>, { - let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref; + let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref; walk_list!(visitor, visit_generic_param, bound_generic_params); visitor.visit_trait_ref(trait_ref) } @@ -720,7 +720,7 @@ impl WalkItemKind for ForeignItemKind { pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result { match bound { - GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref), GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), GenericBound::Use(args, _span) => { walk_list!(visitor, visit_precise_capturing_arg, args); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1273b50dff8..ce744cc56e1 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> { for bound in &bound_pred.bounds { if !matches!( *bound, - GenericBound::Trait(_, TraitBoundModifiers { - polarity: BoundPolarity::Maybe(_), + GenericBound::Trait(PolyTraitRef { + modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. }, .. }) ) { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b19ccc59a71..cc15a48ddc6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1219,11 +1219,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let bound = this.lower_poly_trait_ref( &PolyTraitRef { bound_generic_params: ThinVec::new(), + modifiers: TraitBoundModifiers::NONE, trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, span: t.span, }, itctx, - TraitBoundModifiers::NONE, ); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); @@ -1325,8 +1325,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We can safely ignore constness here since AST validation // takes care of rejecting invalid modifier combinations and // const trait bounds in trait object types. - GenericBound::Trait(ty, modifiers) => { - let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers); + GenericBound::Trait(ty) => { + let trait_ref = this.lower_poly_trait_ref(ty, itctx); Some(trait_ref) } GenericBound::Outlives(lifetime) => { @@ -1974,9 +1974,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { - GenericBound::Trait(p, modifiers) => { - hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx, *modifiers)) - } + GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)), GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(self.lower_lifetime(lifetime)) } @@ -2180,12 +2178,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, p: &PolyTraitRef, itctx: ImplTraitContext, - modifiers: ast::TraitBoundModifiers, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx); - let modifiers = self.lower_trait_bound_modifiers(modifiers); + let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx); + let modifiers = self.lower_trait_bound_modifiers(p.modifiers); hir::PolyTraitRef { bound_generic_params, modifiers, diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 87e3a6871b9..40276a13eeb 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1260,7 +1260,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if !bound_pred.bound_generic_params.is_empty() { for bound in &bound_pred.bounds { match bound { - GenericBound::Trait(t, _) => { + GenericBound::Trait(t) => { if !t.bound_generic_params.is_empty() { self.dcx() .emit_err(errors::NestedLifetimes { span: t.span }); @@ -1280,8 +1280,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { match bound { - GenericBound::Trait(trait_ref, modifiers) => { - match (ctxt, modifiers.constness, modifiers.polarity) { + GenericBound::Trait(trait_ref) => { + match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) { (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) if !self.features.more_maybe_bounds => { @@ -1321,7 +1321,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } // Negative trait bounds are not allowed to have associated constraints - if let BoundPolarity::Negative(_) = modifiers.polarity + if let BoundPolarity::Negative(_) = trait_ref.modifiers.polarity && let Some(segment) = trait_ref.trait_ref.path.segments.last() { match segment.args.as_deref() { @@ -1669,7 +1669,9 @@ fn deny_equality_constraints( }), ) { for bound in bounds { - if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if let GenericBound::Trait(poly) = bound + && poly.modifiers == TraitBoundModifiers::NONE + { if full_path.segments[..full_path.segments.len() - 1] .iter() .map(|segment| segment.ident.name) @@ -1697,7 +1699,9 @@ fn deny_equality_constraints( ) { if ident == potential_param.ident { for bound in bounds { - if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if let ast::GenericBound::Trait(poly) = bound + && poly.modifiers == TraitBoundModifiers::NONE + { suggest(poly, potential_assoc, predicate); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 44a5a2d0baf..f1f2784ad60 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -8,7 +8,6 @@ mod item; use std::borrow::Cow; -use ast::TraitBoundModifiers; use rustc_ast::attr::AttrIdGenerator; use rustc_ast::ptr::P; use rustc_ast::token::{ @@ -1253,6 +1252,27 @@ impl<'a> State<'a> { fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) { self.print_formal_generic_params(&t.bound_generic_params); + + let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers; + match constness { + ast::BoundConstness::Never => {} + ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { + self.word_space(constness.as_str()); + } + } + match asyncness { + ast::BoundAsyncness::Normal => {} + ast::BoundAsyncness::Async(_) => { + self.word_space(asyncness.as_str()); + } + } + match polarity { + ast::BoundPolarity::Positive => {} + ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => { + self.word(polarity.as_str()); + } + } + self.print_trait_ref(&t.trait_ref) } @@ -1740,31 +1760,7 @@ impl<'a> State<'a> { } match bound { - GenericBound::Trait( - tref, - TraitBoundModifiers { constness, asyncness, polarity }, - ) => { - match constness { - ast::BoundConstness::Never => {} - ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { - self.word_space(constness.as_str()); - } - } - - match asyncness { - ast::BoundAsyncness::Normal => {} - ast::BoundAsyncness::Async(_) => { - self.word_space(asyncness.as_str()); - } - } - - match polarity { - ast::BoundPolarity::Positive => {} - ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => { - self.word(polarity.as_str()); - } - } - + GenericBound::Trait(tref) => { self.print_poly_trait_ref(tref); } GenericBound::Outlives(lt) => self.print_lifetime(*lt), diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index e3878d90e41..731945f5cbf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: } fn is_maybe_sized_bound(bound: &GenericBound) -> bool { - if let GenericBound::Trait( - trait_ref, - TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. }, - ) = bound + if let GenericBound::Trait(trait_ref) = bound + && let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } = + trait_ref.modifiers + && is_sized_marker(&trait_ref.trait_ref.path) { - is_sized_marker(&trait_ref.trait_ref.path) + true } else { false } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b5945759d43..2c1ee004e1d 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -143,24 +143,25 @@ impl<'a> ExtCtxt<'a> { ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } } - pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { + pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_generic_params: ThinVec::new(), + modifiers: ast::TraitBoundModifiers { + polarity: ast::BoundPolarity::Positive, + constness: if is_const { + ast::BoundConstness::Maybe(DUMMY_SP) + } else { + ast::BoundConstness::Never + }, + asyncness: ast::BoundAsyncness::Normal, + }, trait_ref: self.trait_ref(path), span, } } pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound { - ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifiers { - polarity: ast::BoundPolarity::Positive, - constness: if is_const { - ast::BoundConstness::Maybe(DUMMY_SP) - } else { - ast::BoundConstness::Never - }, - asyncness: ast::BoundAsyncness::Normal, - }) + ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const)) } pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f32307f6ed4..a9384501547 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> { && let Some(poly) = bounds .iter() .filter_map(|bound| match bound { - ast::GenericBound::Trait(poly, _) => Some(poly), + ast::GenericBound::Trait(poly) => Some(poly), _ => None, }) .last() diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 162ff3b94de..2f19a9b6b20 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -948,8 +948,8 @@ impl<'a> Parser<'a> { { return Ok((false, seg.ident, seg.args.as_deref().cloned())); } else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind - && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] = - bounds.as_slice() + && let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice() + && trait_ref.modifiers == ast::TraitBoundModifiers::NONE && let [seg] = trait_ref.trait_ref.path.segments.as_slice() { return Ok((true, seg.ident, seg.args.as_deref().cloned())); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 625a4cabdf2..6820ccaa18b 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -419,8 +419,13 @@ impl<'a> Parser<'a> { lo: Span, parse_plus: bool, ) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span)); - let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)]; + let poly_trait_ref = PolyTraitRef::new( + generic_params, + path, + TraitBoundModifiers::NONE, + lo.to(self.prev_token.span), + ); + let bounds = vec![GenericBound::Trait(poly_trait_ref)]; self.parse_remaining_bounds(bounds, parse_plus) } @@ -1085,8 +1090,9 @@ impl<'a> Parser<'a> { } } - let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span)); - Ok(GenericBound::Trait(poly_trait, modifiers)) + let poly_trait = + PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span)); + Ok(GenericBound::Trait(poly_trait)) } // recovers a `Fn(..)` parenthesized-style path from `fn(..)` diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index fce5ec36c66..5fbc817b91a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { continue; }; for bound in bounds { - let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound - else { + let ast::GenericBound::Trait(trait_ref) = bound else { continue; }; - if base_error.span == trait_ref.span { + if trait_ref.modifiers == ast::TraitBoundModifiers::NONE + && base_error.span == trait_ref.span + { err.span_suggestion_verbose( constraint.ident.span.between(trait_ref.span), "you might have meant to write a path instead of an associated type bound", @@ -837,7 +838,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); if bounds.iter().all(|bound| match bound { ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true, - ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, + ast::GenericBound::Trait(tr) => tr.span == base_error.span, }) { let mut sugg = vec![]; if base_error.span != start_span { @@ -1210,7 +1211,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let param = generics.params.iter().find_map(|param| { // Only consider type params with exactly one trait bound. if let [bound] = &*param.bounds - && let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound + && let ast::GenericBound::Trait(tref) = bound + && tref.modifiers == ast::TraitBoundModifiers::NONE && tref.span == span && param.ident.span.eq_ctxt(span) { @@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } if let ( [ast::PathSegment { args: None, .. }], - [ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)], + [ast::GenericBound::Trait(poly_trait_ref)], ) = (&type_param_path.segments[..], &bounds[..]) + && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE { if let [ast::PathSegment { ident, args: None, .. }] = &poly_trait_ref.trait_ref.path.segments[..] @@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { && bounded_ty.id == binder { for bound in bounds { - if let ast::GenericBound::Trait(poly_trait_ref, _) = bound + if let ast::GenericBound::Trait(poly_trait_ref) = bound && let span = poly_trait_ref .span .with_hi(poly_trait_ref.trait_ref.path.span.lo()) @@ -3233,7 +3236,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut lt_finder = LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] }; for bound in arg_refs { - if let ast::GenericBound::Trait(trait_ref, _) = bound { + if let ast::GenericBound::Trait(trait_ref) = bound { lt_finder.visit_trait_ref(&trait_ref.trait_ref); } } @@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate( span: DUMMY_SP, bound_generic_params: ThinVec::new(), bounded_ty: ast::ptr::P(ty.clone()), - bounds: vec![ast::GenericBound::Trait( - ast::PolyTraitRef { - bound_generic_params: ThinVec::new(), - trait_ref: ast::TraitRef { - path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None }, - ref_id: DUMMY_NODE_ID, - }, - span: DUMMY_SP, + bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef { + bound_generic_params: ThinVec::new(), + modifiers: ast::TraitBoundModifiers::NONE, + trait_ref: ast::TraitRef { + path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None }, + ref_id: DUMMY_NODE_ID, }, - ast::TraitBoundModifiers::NONE, - )], + span: DUMMY_SP, + })], }; Some(new_where_bound_predicate) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 68f74e52ed7..31585698475 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -783,7 +783,8 @@ pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool { } pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool { - eq_path(&l.trait_ref.path, &r.trait_ref.path) + l.modifiers == r.modifiers + && eq_path(&l.trait_ref.path, &r.trait_ref.path) && over(&l.bound_generic_params, &r.bound_generic_params, |l, r| { eq_generic_param(l, r) }) @@ -817,7 +818,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool { pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool { use GenericBound::*; match (l, r) { - (Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2), + (Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2), (Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident), _ => false, } diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 555a9240798..4d684f3c635 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg { impl Spanned for ast::GenericBound { fn span(&self) -> Span { match *self { - ast::GenericBound::Trait(ref ptr, _) => ptr.span, + ast::GenericBound::Trait(ref ptr) => ptr.span, ast::GenericBound::Outlives(ref l) => l.ident.span, ast::GenericBound::Use(_, span) => span, } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index f75c4f0fad7..a7bd8312bb8 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match *self { - ast::GenericBound::Trait( - ref poly_trait_ref, - ast::TraitBoundModifiers { + ast::GenericBound::Trait(ref poly_trait_ref) => { + let snippet = context.snippet(self.span()); + let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); + let ast::TraitBoundModifiers { constness, asyncness, polarity, - }, - ) => { - let snippet = context.snippet(self.span()); - let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); + } = poly_trait_ref.modifiers; let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); -- cgit 1.4.1-3-g733a5