1
Fork 0

Add more checks for unnamed_field during HIR analysis

This commit is contained in:
clubby789 2024-02-16 18:48:09 +00:00
parent ba824a2e25
commit 62b789fba4
8 changed files with 161 additions and 11 deletions

View file

@ -198,6 +198,8 @@ 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

View file

@ -129,17 +129,20 @@ fn check_unnamed_fields(tcx: TyCtxt<'_>, def: ty::AdtDef<'_>) {
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_anonymous()
&& !adt.repr().c()
&& !adt.is_enum()
{
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(),
});
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) });
}
}
}

View file

@ -943,7 +943,15 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> {
}
}
hir::TyKind::Path(hir::QPath::Resolved(_, hir::Path { res, .. })) => {
self.check_field_in_nested_adt(self.tcx.adt_def(res.def_id()), field.span);
// 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)

View file

@ -661,6 +661,13 @@ pub(crate) struct InvalidUnionField {
pub note: (),
}
#[derive(Diagnostic)]
#[diag(hir_analysis_invalid_unnamed_field_ty)]
pub struct InvalidUnnamedFieldTy {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_return_type_notation_on_non_rpitit)]
pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {