@@ -781,6 +781,65 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
781
781
}
782
782
}
783
783
784
+ /*
785
+ /// In a type definition, we check that unnamed field names are distinct.
786
+ fn check_unnamed_fields_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>) {
787
+ let mut seen_fields: FxHashMap<Ident, Option<Span>> = Default::default();
788
+ fn check_fields_anon_adt_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, seen_fields: &mut FxHashMap<Ident, Option<Span>>) {
789
+ let fields = match &item.kind {
790
+ hir::ItemKind::Struct(fields, _) | hir::ItemKind::Union(fields, _) => fields,
791
+ _ => return,
792
+ };
793
+ for field in fields.fields() {
794
+ if field.ident.name == kw::Underscore {
795
+ if let hir::TyKind::AnonAdt(item_id) = field.ty.kind() {
796
+ let item = tcx.hir().item(item_id);
797
+ check_fields_anon_adt_defn(tcx, item, &mut *seen_fields);
798
+ } else {
799
+ let field_ty = match tcx.type_of(field.def_id).instantiate_identity().ty_adt_def() {
800
+ Some(adt_ty) => adt_ty,
801
+ None => {
802
+ tcx.sess.emit_err(err);
803
+ return;
804
+ }
805
+ };
806
+ if let Some(def_id) = field_ty.did().as_local() {
807
+ let item = tcx.hir().item(hir::ItemId { owner_id: hir::OwnerId { def_id }});
808
+ check_fields_anon_adt_defn(tcx, item, &mut *seen_fields);
809
+ }
810
+ }
811
+ field_ty.flags()
812
+ let inner_adt_def = field_ty.ty_adt_def().expect("expect an adt");
813
+ check_fields_anon_adt_defn(tcx, adt_def, &mut *seen_fields);
814
+ } else {
815
+ let span = field.did.as_local().map(|did| {
816
+ let hir_id = tcx.hir().local_def_id_to_hir_id(did);
817
+ tcx.hir().span(hir_id)
818
+ });
819
+ match seen_fields.get(&ident.normalize_to_macros_2_0()).cloned() {
820
+ Some(Some(prev_span)) => {
821
+ tcx.sess.emit_err(errors::FieldAlreadyDeclared {
822
+ field_name: ident,
823
+ span: f.span,
824
+ prev_span,
825
+ });
826
+ }
827
+ Some(None) => {
828
+ tcx.sess.emit_err(errors::FieldAlreadyDeclared {
829
+ field_name: f.ident,
830
+ span: f.span,
831
+ prev_span,
832
+ });
833
+ }
834
+ None =>
835
+ seen_fields.insert(f.ident.normalize_to_macros_2_0(), f.span);
836
+ }
837
+ }
838
+ }
839
+ }
840
+ }
841
+ */
842
+
784
843
fn convert_variant (
785
844
tcx : TyCtxt < ' _ > ,
786
845
variant_did : Option < LocalDefId > ,
@@ -790,11 +849,17 @@ fn convert_variant(
790
849
adt_kind : ty:: AdtKind ,
791
850
parent_did : LocalDefId ,
792
851
) -> ty:: VariantDef {
852
+ let mut has_unnamed_fields = false ;
793
853
let mut seen_fields: FxHashMap < Ident , Span > = Default :: default ( ) ;
794
854
let fields = def
795
855
. fields ( )
796
856
. iter ( )
797
- . map ( |f| {
857
+ . inspect ( |f| {
858
+ // Skip the unnamed field here, we will check it later.
859
+ if f. ident . name == kw:: Underscore {
860
+ has_unnamed_fields = true ;
861
+ return ;
862
+ }
798
863
let dup_span = seen_fields. get ( & f. ident . normalize_to_macros_2_0 ( ) ) . cloned ( ) ;
799
864
if let Some ( prev_span) = dup_span {
800
865
tcx. sess . emit_err ( errors:: FieldAlreadyDeclared {
@@ -805,12 +870,11 @@ fn convert_variant(
805
870
} else {
806
871
seen_fields. insert ( f. ident . normalize_to_macros_2_0 ( ) , f. span ) ;
807
872
}
808
-
809
- ty:: FieldDef {
810
- did : f. def_id . to_def_id ( ) ,
811
- name : f. ident . name ,
812
- vis : tcx. visibility ( f. def_id ) ,
813
- }
873
+ } )
874
+ . map ( |f| ty:: FieldDef {
875
+ did : f. def_id . to_def_id ( ) ,
876
+ name : f. ident . name ,
877
+ vis : tcx. visibility ( f. def_id ) ,
814
878
} )
815
879
. collect ( ) ;
816
880
let recovered = match def {
@@ -829,6 +893,7 @@ fn convert_variant(
829
893
adt_kind == AdtKind :: Struct && tcx. has_attr ( parent_did, sym:: non_exhaustive)
830
894
|| variant_did
831
895
. is_some_and ( |variant_did| tcx. has_attr ( variant_did, sym:: non_exhaustive) ) ,
896
+ has_unnamed_fields,
832
897
)
833
898
}
834
899
@@ -839,6 +904,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
839
904
bug ! ( ) ;
840
905
} ;
841
906
907
+ let is_anonymous = item. ident . name == sym:: anon;
842
908
let repr = tcx. repr_options_of_def ( def_id. to_def_id ( ) ) ;
843
909
let ( kind, variants) = match & item. kind {
844
910
ItemKind :: Enum ( def, _) => {
@@ -889,7 +955,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
889
955
}
890
956
_ => bug ! ( ) ,
891
957
} ;
892
- tcx. mk_adt_def ( def_id. to_def_id ( ) , kind, variants, repr)
958
+ tcx. mk_adt_def ( def_id. to_def_id ( ) , kind, variants, repr, is_anonymous )
893
959
}
894
960
895
961
fn trait_def ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> ty:: TraitDef {
0 commit comments