diff options
| author | Frank King <frankking1729@gmail.com> | 2024-01-04 21:53:06 +0800 |
|---|---|---|
| committer | Frank King <frankking1729@gmail.com> | 2024-02-12 12:47:23 +0800 |
| commit | 879a1e571305a0fb35ef6cc4297f9230fca95be5 (patch) | |
| tree | 232e06c6b3eefcc81f10f825a430f04a7325c498 /compiler/rustc_hir_analysis/src | |
| parent | 084ce5bdb5f7dc1c725f6770a8de281165ba3b0a (diff) | |
| download | rust-879a1e571305a0fb35ef6cc4297f9230fca95be5.tar.gz rust-879a1e571305a0fb35ef6cc4297f9230fca95be5.zip | |
Lower anonymous structs or unions to HIR
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/mod.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 82 |
2 files changed, 87 insertions, 8 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 1ae3ebaebbb..a643614d33d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2457,6 +2457,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::TyKind::Tup(fields) => { Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.ast_ty_to_ty(t))) } + hir::TyKind::AnonAdt(item_id) => { + let did = item_id.owner_id.def_id; + let adt_def = tcx.adt_def(did); + let generics = tcx.generics_of(did); + + debug!("ast_ty_to_ty_inner(AnonAdt): generics={:?}", generics); + let args = ty::GenericArgs::for_item(tcx, did.to_def_id(), |param, _| { + tcx.mk_param_from_def(param) + }); + debug!("ast_ty_to_ty_inner(AnonAdt): args={:?}", args); + + Ty::new_adt(tcx, adt_def, tcx.mk_args(args)) + } hir::TyKind::BareFn(bf) => { require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f458ff01c10..768b07069c8 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -789,6 +789,65 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { } } +/* +/// In a type definition, we check that unnamed field names are distinct. +fn check_unnamed_fields_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>) { + let mut seen_fields: FxHashMap<Ident, Option<Span>> = Default::default(); + fn check_fields_anon_adt_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, seen_fields: &mut FxHashMap<Ident, Option<Span>>) { + let fields = match &item.kind { + hir::ItemKind::Struct(fields, _) | hir::ItemKind::Union(fields, _) => fields, + _ => return, + }; + for field in fields.fields() { + if field.ident.name == kw::Underscore { + if let hir::TyKind::AnonAdt(item_id) = field.ty.kind() { + let item = tcx.hir().item(item_id); + check_fields_anon_adt_defn(tcx, item, &mut *seen_fields); + } else { + let field_ty = match tcx.type_of(field.def_id).instantiate_identity().ty_adt_def() { + Some(adt_ty) => adt_ty, + None => { + tcx.sess.emit_err(err); + return; + } + }; + if let Some(def_id) = field_ty.did().as_local() { + let item = tcx.hir().item(hir::ItemId { owner_id: hir::OwnerId { def_id }}); + check_fields_anon_adt_defn(tcx, item, &mut *seen_fields); + } + } + field_ty.flags() + let inner_adt_def = field_ty.ty_adt_def().expect("expect an adt"); + check_fields_anon_adt_defn(tcx, adt_def, &mut *seen_fields); + } else { + let span = field.did.as_local().map(|did| { + let hir_id = tcx.hir().local_def_id_to_hir_id(did); + tcx.hir().span(hir_id) + }); + match seen_fields.get(&ident.normalize_to_macros_2_0()).cloned() { + Some(Some(prev_span)) => { + tcx.sess.emit_err(errors::FieldAlreadyDeclared { + field_name: ident, + span: f.span, + prev_span, + }); + } + Some(None) => { + tcx.sess.emit_err(errors::FieldAlreadyDeclared { + field_name: f.ident, + span: f.span, + prev_span, + }); + } + None => + seen_fields.insert(f.ident.normalize_to_macros_2_0(), f.span); + } + } + } + } +} + */ + fn convert_variant( tcx: TyCtxt<'_>, variant_did: Option<LocalDefId>, @@ -798,11 +857,17 @@ fn convert_variant( adt_kind: ty::AdtKind, parent_did: LocalDefId, ) -> ty::VariantDef { + let mut has_unnamed_fields = false; let mut seen_fields: FxHashMap<Ident, Span> = Default::default(); let fields = def .fields() .iter() - .map(|f| { + .inspect(|f| { + // Skip the unnamed field here, we will check it later. + if f.ident.name == kw::Underscore { + has_unnamed_fields = true; + return; + } let dup_span = seen_fields.get(&f.ident.normalize_to_macros_2_0()).cloned(); if let Some(prev_span) = dup_span { tcx.dcx().emit_err(errors::FieldAlreadyDeclared { @@ -813,12 +878,11 @@ fn convert_variant( } else { seen_fields.insert(f.ident.normalize_to_macros_2_0(), f.span); } - - ty::FieldDef { - did: f.def_id.to_def_id(), - name: f.ident.name, - vis: tcx.visibility(f.def_id), - } + }) + .map(|f| ty::FieldDef { + did: f.def_id.to_def_id(), + name: f.ident.name, + vis: tcx.visibility(f.def_id), }) .collect(); let recovered = match def { @@ -837,6 +901,7 @@ fn convert_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, ) } @@ -847,6 +912,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 = tcx.repr_options_of_def(def_id.to_def_id()); let (kind, variants) = match &item.kind { ItemKind::Enum(def, _) => { @@ -897,7 +963,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) + tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr, is_anonymous) } fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { |
