fix: Error on illegal [const]s inside blocks within legal positions

This commit is contained in:
Shoyu Vanilla
2025-08-01 00:23:36 +09:00
parent 7cd950546b
commit 7d78968bd0
7 changed files with 140 additions and 42 deletions

View File

@@ -241,6 +241,10 @@ ast_passes_tilde_const_disallowed = `[const]` is not allowed here
.trait_assoc_ty = associated types in non-`const` traits cannot have `[const]` trait bounds
.trait_impl_assoc_ty = associated types in non-const impls cannot have `[const]` trait bounds
.inherent_assoc_ty = inherent associated types cannot have `[const]` trait bounds
.struct = structs cannot have `[const]` trait bounds
.enum = enums cannot have `[const]` trait bounds
.union = unions cannot have `[const]` trait bounds
.anon_const = anonymous constants cannot have `[const]` trait bounds
.object = trait objects cannot have `[const]` trait bounds
.item = this item cannot have `[const]` trait bounds

View File

@@ -1124,7 +1124,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
);
}
}
visit::walk_item(self, item)
self.with_tilde_const(Some(TildeConstReason::Enum { span: item.span }), |this| {
visit::walk_item(this, item)
});
}
ItemKind::Trait(box Trait {
constness,
@@ -1175,26 +1177,32 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
visit::walk_item(self, item)
}
ItemKind::Struct(ident, generics, vdata) => match vdata {
VariantData::Struct { fields, .. } => {
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
self.visit_generics(generics);
walk_list!(self, visit_field_def, fields);
}
_ => visit::walk_item(self, item),
},
ItemKind::Struct(ident, generics, vdata) => {
self.with_tilde_const(Some(TildeConstReason::Struct { span: item.span }), |this| {
match vdata {
VariantData::Struct { fields, .. } => {
this.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
this.visit_generics(generics);
walk_list!(this, visit_field_def, fields);
}
_ => visit::walk_item(this, item),
}
})
}
ItemKind::Union(ident, generics, vdata) => {
if vdata.fields().is_empty() {
self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
}
match vdata {
VariantData::Struct { fields, .. } => {
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
self.visit_generics(generics);
walk_list!(self, visit_field_def, fields);
self.with_tilde_const(Some(TildeConstReason::Union { span: item.span }), |this| {
match vdata {
VariantData::Struct { fields, .. } => {
this.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
this.visit_generics(generics);
walk_list!(this, visit_field_def, fields);
}
_ => visit::walk_item(this, item),
}
_ => visit::walk_item(self, item),
}
});
}
ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
self.check_defaultness(item.span, *defaultness);
@@ -1623,6 +1631,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
_ => self.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)),
}
}
fn visit_anon_const(&mut self, anon_const: &'a AnonConst) {
self.with_tilde_const(
Some(TildeConstReason::AnonConst { span: anon_const.value.span }),
|this| visit::walk_anon_const(this, anon_const),
)
}
}
/// When encountering an equality constraint in a `where` clause, emit an error. If the code seems

View File

@@ -623,6 +623,26 @@ pub(crate) enum TildeConstReason {
#[primary_span]
span: Span,
},
#[note(ast_passes_struct)]
Struct {
#[primary_span]
span: Span,
},
#[note(ast_passes_enum)]
Enum {
#[primary_span]
span: Span,
},
#[note(ast_passes_union)]
Union {
#[primary_span]
span: Span,
},
#[note(ast_passes_anon_const)]
AnonConst {
#[primary_span]
span: Span,
},
#[note(ast_passes_object)]
TraitObject,
#[note(ast_passes_item)]