@@ -789,6 +789,65 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
789
789
}
790
790
}
791
791
792
+ /*
793
+ /// In a type definition, we check that unnamed field names are distinct.
794
+ fn check_unnamed_fields_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>) {
795
+ let mut seen_fields: FxHashMap<Ident, Option<Span>> = Default::default();
796
+ fn check_fields_anon_adt_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, seen_fields: &mut FxHashMap<Ident, Option<Span>>) {
797
+ let fields = match &item.kind {
798
+ hir::ItemKind::Struct(fields, _) | hir::ItemKind::Union(fields, _) => fields,
799
+ _ => return,
800
+ };
801
+ for field in fields.fields() {
802
+ if field.ident.name == kw::Underscore {
803
+ if let hir::TyKind::AnonAdt(item_id) = field.ty.kind() {
804
+ let item = tcx.hir().item(item_id);
805
+ check_fields_anon_adt_defn(tcx, item, &mut *seen_fields);
806
+ } else {
807
+ let field_ty = match tcx.type_of(field.def_id).instantiate_identity().ty_adt_def() {
808
+ Some(adt_ty) => adt_ty,
809
+ None => {
810
+ tcx.sess.emit_err(err);
811
+ return;
812
+ }
813
+ };
814
+ if let Some(def_id) = field_ty.did().as_local() {
815
+ let item = tcx.hir().item(hir::ItemId { owner_id: hir::OwnerId { def_id }});
816
+ check_fields_anon_adt_defn(tcx, item, &mut *seen_fields);
817
+ }
818
+ }
819
+ field_ty.flags()
820
+ let inner_adt_def = field_ty.ty_adt_def().expect("expect an adt");
821
+ check_fields_anon_adt_defn(tcx, adt_def, &mut *seen_fields);
822
+ } else {
823
+ let span = field.did.as_local().map(|did| {
824
+ let hir_id = tcx.hir().local_def_id_to_hir_id(did);
825
+ tcx.hir().span(hir_id)
826
+ });
827
+ match seen_fields.get(&ident.normalize_to_macros_2_0()).cloned() {
828
+ Some(Some(prev_span)) => {
829
+ tcx.sess.emit_err(errors::FieldAlreadyDeclared {
830
+ field_name: ident,
831
+ span: f.span,
832
+ prev_span,
833
+ });
834
+ }
835
+ Some(None) => {
836
+ tcx.sess.emit_err(errors::FieldAlreadyDeclared {
837
+ field_name: f.ident,
838
+ span: f.span,
839
+ prev_span,
840
+ });
841
+ }
842
+ None =>
843
+ seen_fields.insert(f.ident.normalize_to_macros_2_0(), f.span);
844
+ }
845
+ }
846
+ }
847
+ }
848
+ }
849
+ */
850
+
792
851
fn convert_variant (
793
852
tcx : TyCtxt < ' _ > ,
794
853
variant_did : Option < LocalDefId > ,
@@ -798,11 +857,17 @@ fn convert_variant(
798
857
adt_kind : ty:: AdtKind ,
799
858
parent_did : LocalDefId ,
800
859
) -> ty:: VariantDef {
860
+ let mut has_unnamed_fields = false ;
801
861
let mut seen_fields: FxHashMap < Ident , Span > = Default :: default ( ) ;
802
862
let fields = def
803
863
. fields ( )
804
864
. iter ( )
805
- . map ( |f| {
865
+ . inspect ( |f| {
866
+ // Skip the unnamed field here, we will check it later.
867
+ if f. ident . name == kw:: Underscore {
868
+ has_unnamed_fields = true ;
869
+ return ;
870
+ }
806
871
let dup_span = seen_fields. get ( & f. ident . normalize_to_macros_2_0 ( ) ) . cloned ( ) ;
807
872
if let Some ( prev_span) = dup_span {
808
873
tcx. dcx ( ) . emit_err ( errors:: FieldAlreadyDeclared {
@@ -813,12 +878,11 @@ fn convert_variant(
813
878
} else {
814
879
seen_fields. insert ( f. ident . normalize_to_macros_2_0 ( ) , f. span ) ;
815
880
}
816
-
817
- ty:: FieldDef {
818
- did : f. def_id . to_def_id ( ) ,
819
- name : f. ident . name ,
820
- vis : tcx. visibility ( f. def_id ) ,
821
- }
881
+ } )
882
+ . map ( |f| ty:: FieldDef {
883
+ did : f. def_id . to_def_id ( ) ,
884
+ name : f. ident . name ,
885
+ vis : tcx. visibility ( f. def_id ) ,
822
886
} )
823
887
. collect ( ) ;
824
888
let recovered = match def {
@@ -837,6 +901,7 @@ fn convert_variant(
837
901
adt_kind == AdtKind :: Struct && tcx. has_attr ( parent_did, sym:: non_exhaustive)
838
902
|| variant_did
839
903
. is_some_and ( |variant_did| tcx. has_attr ( variant_did, sym:: non_exhaustive) ) ,
904
+ has_unnamed_fields,
840
905
)
841
906
}
842
907
@@ -847,6 +912,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
847
912
bug ! ( "expected ADT to be an item" ) ;
848
913
} ;
849
914
915
+ let is_anonymous = item. ident . name == kw:: Empty ;
850
916
let repr = tcx. repr_options_of_def ( def_id. to_def_id ( ) ) ;
851
917
let ( kind, variants) = match & item. kind {
852
918
ItemKind :: Enum ( def, _) => {
@@ -897,7 +963,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
897
963
}
898
964
_ => bug ! ( "{:?} is not an ADT" , item. owner_id. def_id) ,
899
965
} ;
900
- tcx. mk_adt_def ( def_id. to_def_id ( ) , kind, variants, repr)
966
+ tcx. mk_adt_def ( def_id. to_def_id ( ) , kind, variants, repr, is_anonymous )
901
967
}
902
968
903
969
fn trait_def ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> ty:: TraitDef {
0 commit comments