Skip to content

Commit

Permalink
Create node Item and AdtDef for anonymous adts
Browse files Browse the repository at this point in the history
  • Loading branch information
frank-king committed Sep 4, 2023
1 parent b2da370 commit 1df9b8a
Show file tree
Hide file tree
Showing 51 changed files with 195 additions and 328 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2093,9 +2093,9 @@ pub enum TyKind {
/// A tuple (`(A, B, C, D,...)`).
Tup(ThinVec<P<Ty>>),
/// An anonymous struct type i.e. `struct { foo: Type }`
AnonStruct(ThinVec<FieldDef>),
AnonStruct(NodeId, ThinVec<FieldDef>),
/// An anonymous union type i.e. `union { bar: Type }`
AnonUnion(ThinVec<FieldDef>),
AnonUnion(NodeId, ThinVec<FieldDef>),
/// A path (`module::module::...::Type`), optionally
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
///
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,8 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
}
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
TyKind::AnonStruct(fields) | TyKind::AnonUnion(fields) => {
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {
vis.visit_id(id);
fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
TyKind::MacCall(mac) => visitor.visit_mac_call(mac),
TyKind::Never | TyKind::CVarArgs => {}
TyKind::AnonStruct(ref fields, ..) | TyKind::AnonUnion(ref fields, ..) => {
TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => {
walk_list!(visitor, visit_field_def, fields)
}
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

pub(super) fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
pub(super) fn lower_field_def(
&mut self,
(index, f): (usize, &FieldDef),
) -> hir::FieldDef<'hir> {
let ty = if let TyKind::Path(qself, path) = &f.ty.kind {
let t = self.lower_path_ty(
&f.ty,
Expand Down
42 changes: 33 additions & 9 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,15 +1293,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::Err => {
hir::TyKind::Err(self.tcx.sess.delay_span_bug(t.span, "TyKind::Err lowered"))
}
TyKind::AnonStruct(fields) => {
hir::TyKind::AnonStruct(
self.arena.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
)
}
TyKind::AnonUnion(fields) => {
hir::TyKind::AnonUnion(
self.arena.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
)
TyKind::AnonStruct(def_node_id, fields) | TyKind::AnonUnion(def_node_id, fields) => {
let def_path_data = match &t.kind {
TyKind::AnonStruct(..) => DefPathData::AnonStruct,
_ => DefPathData::AnonUnion,
};
let def_id = self.create_def(
self.current_hir_id_owner.def_id,
*def_node_id,
def_path_data,
t.span,
);
debug!(?def_id);
let owner_id = hir::OwnerId { def_id };
self.with_hir_id_owner(*def_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, false);
let generics = hir::Generics::empty();
let kind = match &t.kind {
TyKind::AnonStruct(..) => hir::ItemKind::Struct(variant_data, generics),
_ => hir::ItemKind::Union(variant_data, generics),
};
hir::OwnerNode::Item(this.arena.alloc(hir::Item {
ident: Ident::empty(),
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)),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ impl<'a> AstValidator<'a> {
}
}
}
TyKind::AnonStruct(ref fields, ..) | TyKind::AnonUnion(ref fields, ..) => {
TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => {
walk_list!(self, visit_field_def, fields)
}
_ => visit::walk_ty(self, t),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1053,11 +1053,11 @@ impl<'a> State<'a> {
}
self.pclose();
}
ast::TyKind::AnonStruct(fields) => {
ast::TyKind::AnonStruct(_, fields) => {
self.head("struct");
self.print_record_struct_body(&fields, ty.span);
}
ast::TyKind::AnonUnion(fields) => {
ast::TyKind::AnonUnion(_, fields) => {
self.head("union");
self.print_record_struct_body(&fields, ty.span);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
enum_type_di_node,
std::iter::once((
variant_index,
Cow::from(enum_adt_def.variant(variant_index).name_ref().as_str()),
Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
)),
);

Expand Down Expand Up @@ -399,7 +399,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
cx,
enum_type_di_node,
variant_indices.clone().map(|variant_index| {
let variant_name = Cow::from(enum_adt_def.variant(variant_index).name_ref().as_str());
let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
(variant_index, variant_name)
}),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
tag_base_type(cx, enum_type_and_layout),
enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
let name = Cow::from(enum_adt_def.variant(variant_index).name_ref().as_str());
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
(name, discr.val)
}),
containing_scope,
Expand Down Expand Up @@ -263,7 +263,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
enum_type_and_layout.ty,
variant_index,
),
variant_def.name().as_str(),
variant_def.name.as_str(),
// NOTE: We use size and align of enum_type, not from variant_layout:
size_and_align_of(enum_type_and_layout),
Some(enum_type_di_node),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
.variant_range()
.map(|variant_index| VariantMemberInfo {
variant_index,
variant_name: Cow::from(enum_adt_def.variant(variant_index).name_ref().as_str()),
variant_name: Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
cx,
enum_type_and_layout,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn uncached_llvm_type<'a, 'tcx>(
(layout.ty.kind(), &layout.variants)
{
if def.is_enum() && !def.variants().is_empty() {
write!(&mut name, "::{}", def.variant(index).name()).unwrap();
write!(&mut name, "::{}", def.variant(index).name).unwrap();
}
}
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
new_op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
let name = match old_op.layout.ty.kind() {
ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name()),
ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name),
// Generators also have variants
ty::Generator(..) => PathElem::GeneratorState(variant_id),
_ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_hir/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ pub enum DefPathData {
ImplTrait,
/// `impl Trait` generated associated type node.
ImplTraitAssocTy,
/// An anonymous struct type i.e. `struct { foo: Type }`
AnonStruct,
/// An anonymous union type i.e. `union { bar: Type }`
AnonUnion,
}

impl Definitions {
Expand Down Expand Up @@ -405,7 +409,7 @@ impl DefPathData {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),

Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
| ImplTrait | ImplTraitAssocTy => None,
| ImplTrait | ImplTraitAssocTy | AnonStruct | AnonUnion => None,
}
}

Expand All @@ -424,7 +428,9 @@ impl DefPathData {
ClosureExpr => DefPathDataName::Anon { namespace: sym::closure },
Ctor => DefPathDataName::Anon { namespace: sym::constructor },
AnonConst => DefPathDataName::Anon { namespace: sym::constant },
ImplTrait | ImplTraitAssocTy => DefPathDataName::Anon { namespace: sym::opaque },
ImplTrait | ImplTraitAssocTy | AnonStruct | AnonUnion => {
DefPathDataName::Anon { namespace: sym::opaque }
}
}
}
}
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2713,10 +2713,8 @@ pub enum TyKind<'hir> {
Never,
/// A tuple (`(A, B, C, D, ...)`).
Tup(&'hir [Ty<'hir>]),
/// An anonymous struct type i.e. `struct { foo: Type }`
AnonStruct(&'hir [FieldDef<'hir>]),
/// An anonymous union type i.e. `union { bar: Type }`
AnonUnion(&'hir [FieldDef<'hir>]),
/// An anonymous struct or union type i.e. `struct { foo: Type }` or `union { foo: Type }`
AnonAdt(ItemId),
/// A path to a type definition (`module::module::...::Type`), or an
/// associated type (e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`).
///
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,8 +862,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
}
TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
TyKind::Infer | TyKind::Err(_) => {}
TyKind::AnonStruct(fields) | TyKind::AnonUnion(fields) => {
walk_list!(visitor, visit_field_def, fields);
TyKind::AnonAdt(item_id) => {
visitor.visit_nested_item(item_id);
}
}
}
Expand Down
62 changes: 5 additions & 57 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&adt_def
.variants()
.iter()
.map(|variant| variant.name())
.map(|variant| variant.name)
.collect::<Vec<Symbol>>(),
assoc_ident.name,
None,
Expand Down Expand Up @@ -2422,6 +2422,10 @@ 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 adt_def = crate::collect::adt_def(tcx, item_id.owner_id.def_id);
Ty::new_adt(tcx, adt_def, tcx.mk_args(&[]))
}
hir::TyKind::BareFn(bf) => {
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);

Expand Down Expand Up @@ -2524,27 +2528,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.ty_infer(None, ast_ty.span)
}
hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
hir::TyKind::AnonStruct(fields,) | hir::TyKind::AnonUnion(fields) => {
let repr = tcx.repr_options_of_def(ast_ty.hir_id.owner.to_def_id());
if !repr.c() {
// tcx.sess.emit_err(todo!());
}
let adt_kind = match ast_ty.kind {
hir::TyKind::AnonStruct(..) => ty::AdtKind::Struct,
_ => ty::AdtKind::Union,
};
let field_def = tcx.hir().expect_field(tcx.hir().parent_id(ast_ty.hir_id));
let did = field_def.def_id;
let variants = std::iter::once(convert_variant(
tcx,
did,
fields,
adt_kind,
))
.collect();
let adt_def = tcx.mk_adt_def(did.to_def_id(), adt_kind, variants, repr);
Ty::new_adt(tcx, adt_def, tcx.mk_args(&[]))
}
};

self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
Expand Down Expand Up @@ -2834,38 +2817,3 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Some(r)
}
}

fn convert_variant(
tcx: TyCtxt<'_>,
did: LocalDefId,
fields: &[hir::FieldDef<'_>],
adt_kind: ty::AdtKind,
) -> ty::VariantDef {
let mut seen_fields: FxHashMap<Ident, Span> = Default::default();
let fields = fields
.iter()
.map(|f| {
let dup_span = seen_fields.get(&f.ident.normalize_to_macros_2_0()).cloned();
if let Some(prev_span) = dup_span {
tcx.sess.emit_err(crate::errors::FieldAlreadyDeclared {
field_name: f.ident,
span: f.span,
prev_span,
});
} 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),
}
})
.collect();
ty::VariantDef::new_anon(
did.to_def_id(),
fields,
adt_kind,
)
}
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1323,8 +1323,8 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
idx.as_u32().checked_sub(distance_to_explicit).map(VariantIdx::from_u32)
{
let explicit_variant = adt.variant(explicit_idx);
let ve_ident = var.name();
let ex_ident = explicit_variant.name();
let ve_ident = var.name;
let ex_ident = explicit_variant.name;
let sp = if distance_to_explicit > 1 { "variants" } else { "variant" };

err.span_label(
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
}
}

pub(crate) fn convert_variant(
fn convert_variant(
tcx: TyCtxt<'_>,
variant_did: Option<LocalDefId>,
ident: Ident,
Expand Down Expand Up @@ -827,7 +827,7 @@ pub(crate) fn convert_variant(
)
}

fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
pub(crate) fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
use rustc_hir::*;

let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
Expand Down Expand Up @@ -885,7 +885,11 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
}
_ => bug!(),
};
tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
if item.ident.name == kw::Empty {
tcx.mk_anon_adt_def(def_id.to_def_id(), kind, variants, repr)
} else {
tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
}
}

fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,7 @@ impl<'a> State<'a> {
hir::TyKind::Infer => {
self.word("_");
}
hir::TyKind::AnonStruct(fields) => {
self.word("struct");
self.print_variant_struct(ty.span, fields);
}
hir::TyKind::AnonUnion(fields) => {
self.word("union");
self.print_variant_struct(ty.span, fields);
}
hir::TyKind::AnonAdt(..) => self.word("/* anonymous adt */"),
}
self.end()
}
Expand Down
Loading

0 comments on commit 1df9b8a

Please sign in to comment.