From 231a3a241bbf91771533d3c3b35e868a50ee6d15 Mon Sep 17 00:00:00 2001 From: lapla Date: Tue, 25 Nov 2025 17:53:48 +0900 Subject: [PATCH] Deny const auto traits --- compiler/rustc_ast_passes/messages.ftl | 3 +++ compiler/rustc_ast_passes/src/ast_validation.rs | 8 ++++++++ compiler/rustc_ast_passes/src/errors.rs | 8 ++++++++ tests/ui/traits/const-traits/const-auto-trait.rs | 6 ++++++ tests/ui/traits/const-traits/const-auto-trait.stderr | 10 ++++++++++ 5 files changed, 35 insertions(+) create mode 100644 tests/ui/traits/const-traits/const-auto-trait.rs create mode 100644 tests/ui/traits/const-traits/const-auto-trait.stderr diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 9bdbcf6ab907..f03c7dd5b9d5 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -89,6 +89,9 @@ ast_passes_const_and_coroutine = functions cannot be both `const` and `{$corouti .coroutine = `{$coroutine_kind}` because of this .label = {""} +ast_passes_const_auto_trait = auto traits cannot be const + .help = remove the `const` keyword + ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types ast_passes_const_without_body = diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 163dbc3350ba..e57f8da26769 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -820,6 +820,12 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::ModuleNonAscii { span: ident.span, name: ident.name }); } + fn deny_const_auto_traits(&self, constness: Const) { + if let Const::Yes(span) = constness { + self.dcx().emit_err(errors::ConstAutoTrait { span }); + } + } + fn deny_generic_params(&self, generics: &Generics, ident_span: Span) { if !generics.params.is_empty() { self.dcx() @@ -1257,6 +1263,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }) => { self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident); if *is_auto == IsAuto::Yes { + // For why we reject `const auto trait`, see rust-lang/rust#149285. + self.deny_const_auto_traits(*constness); // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, ident.span); self.deny_super_traits(bounds, ident.span); diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 02e6ecfbaee7..c700ae517140 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -429,6 +429,14 @@ pub(crate) struct AutoTraitItems { pub ident: Span, } +#[derive(Diagnostic)] +#[diag(ast_passes_const_auto_trait)] +#[help] +pub(crate) struct ConstAutoTrait { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_generic_before_constraints)] pub(crate) struct ArgsBeforeConstraint { diff --git a/tests/ui/traits/const-traits/const-auto-trait.rs b/tests/ui/traits/const-traits/const-auto-trait.rs new file mode 100644 index 000000000000..06558df4623f --- /dev/null +++ b/tests/ui/traits/const-traits/const-auto-trait.rs @@ -0,0 +1,6 @@ +#![feature(auto_traits, const_trait_impl)] + +const auto trait Marker {} +//~^ ERROR: auto traits cannot be const + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-auto-trait.stderr b/tests/ui/traits/const-traits/const-auto-trait.stderr new file mode 100644 index 000000000000..cb8ff8001ba0 --- /dev/null +++ b/tests/ui/traits/const-traits/const-auto-trait.stderr @@ -0,0 +1,10 @@ +error: auto traits cannot be const + --> $DIR/const-auto-trait.rs:3:1 + | +LL | const auto trait Marker {} + | ^^^^^ + | + = help: remove the `const` keyword + +error: aborting due to 1 previous error +