From 08c391ca09ef577a6d607c2e208dcde10902dfdc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Jul 2025 10:06:49 +0000 Subject: [PATCH] Temporarily allow `const impl` and `impl const` at the same time to migrate --- compiler/rustc_parse/src/parser/item.rs | 50 +++---------------- tests/ui/parser/issues/issue-81806.rs | 7 +-- tests/ui/parser/issues/issue-81806.stderr | 32 +++++++----- .../const-traits/const-impl-norecover.rs | 2 +- .../const-traits/const-impl-norecover.stderr | 10 ++-- .../const-traits/const-impl-recovery.rs | 6 ++- .../const-traits/const-impl-recovery.stderr | 26 ---------- 7 files changed, 42 insertions(+), 91 deletions(-) delete mode 100644 tests/ui/traits/const-traits/const-impl-recovery.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c1b920401483..1d30c34530e3 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -562,9 +562,7 @@ fn parse_item_impl( attrs: &mut AttrVec, defaultness: Defaultness, ) -> PResult<'a, ItemKind> { - if self.eat_keyword(exp!(Const)) { - return self.recover_const_impl(self.prev_token.span, attrs, defaultness); - } + let mut constness = self.parse_constness(Case::Sensitive); let safety = self.parse_safety(Case::Sensitive); self.expect_keyword(exp!(Impl))?; @@ -579,7 +577,11 @@ fn parse_item_impl( generics }; - let constness = self.parse_constness(Case::Sensitive); + if let Const::No = constness { + // FIXME(const_trait_impl): disallow `impl const Trait` + constness = self.parse_constness(Case::Sensitive); + } + if let Const::Yes(span) = constness { self.psess.gated_spans.gate(sym::const_trait_impl, span); } @@ -1355,46 +1357,6 @@ fn recover_const_mut(&mut self, const_span: Span) { } } - /// Recover on `const impl` with `const` already eaten. - fn recover_const_impl( - &mut self, - const_span: Span, - attrs: &mut AttrVec, - defaultness: Defaultness, - ) -> PResult<'a, ItemKind> { - let impl_span = self.token.span; - let err = self.expected_ident_found_err(); - - // Only try to recover if this is implementing a trait for a type - let mut item_kind = match self.parse_item_impl(attrs, defaultness) { - Ok(item_kind) => item_kind, - Err(recovery_error) => { - // Recovery failed, raise the "expected identifier" error - recovery_error.cancel(); - return Err(err); - } - }; - - match &mut item_kind { - ItemKind::Impl(Impl { of_trait: Some(of_trait), .. }) => { - of_trait.constness = Const::Yes(const_span); - - let before_trait = of_trait.trait_ref.path.span.shrink_to_lo(); - let const_up_to_impl = const_span.with_hi(impl_span.lo()); - err.with_multipart_suggestion( - "you might have meant to write a const trait impl", - vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())], - Applicability::MaybeIncorrect, - ) - .emit(); - } - ItemKind::Impl { .. } => return Err(err), - _ => unreachable!(), - } - - Ok(item_kind) - } - /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in /// `mutability`. /// diff --git a/tests/ui/parser/issues/issue-81806.rs b/tests/ui/parser/issues/issue-81806.rs index ca86788dff79..bc2a97f58b85 100644 --- a/tests/ui/parser/issues/issue-81806.rs +++ b/tests/ui/parser/issues/issue-81806.rs @@ -1,5 +1,6 @@ -trait T { const -impl //~ ERROR: expected identifier, found keyword `impl` -} +trait T { +const //~ ERROR: const trait impls are experimental +impl +} //~ ERROR: expected type, found `}` fn main() {} diff --git a/tests/ui/parser/issues/issue-81806.stderr b/tests/ui/parser/issues/issue-81806.stderr index f1287b82fa57..2f15a5081d48 100644 --- a/tests/ui/parser/issues/issue-81806.stderr +++ b/tests/ui/parser/issues/issue-81806.stderr @@ -1,17 +1,25 @@ -error: expected identifier, found keyword `impl` +error: expected type, found `}` + --> $DIR/issue-81806.rs:4:1 + | +LL | trait T { + | - while parsing this item list starting here +... +LL | } + | ^ + | | + | expected type + | the item list ends here + +error[E0658]: const trait impls are experimental --> $DIR/issue-81806.rs:2:1 | -LL | trait T { const - | - while parsing this item list starting here -LL | impl - | ^^^^ expected identifier, found keyword -LL | } - | - the item list ends here +LL | const + | ^^^^^ | -help: escape `impl` to use it as an identifier - | -LL | r#impl - | ++ + = note: see issue #143874 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/const-impl-norecover.rs b/tests/ui/traits/const-traits/const-impl-norecover.rs index bed4e9fd1e61..31dc3471ca6c 100644 --- a/tests/ui/traits/const-traits/const-impl-norecover.rs +++ b/tests/ui/traits/const-traits/const-impl-norecover.rs @@ -2,7 +2,7 @@ struct Foo; -const impl Foo { //~ ERROR: expected identifier, found keyword +const impl Foo { //~ ERROR: inherent impls cannot be const fn bar() {} } diff --git a/tests/ui/traits/const-traits/const-impl-norecover.stderr b/tests/ui/traits/const-traits/const-impl-norecover.stderr index efa72463c5e9..78eb220343c9 100644 --- a/tests/ui/traits/const-traits/const-impl-norecover.stderr +++ b/tests/ui/traits/const-traits/const-impl-norecover.stderr @@ -1,8 +1,12 @@ -error: expected identifier, found keyword `impl` - --> $DIR/const-impl-norecover.rs:5:7 +error: inherent impls cannot be const + --> $DIR/const-impl-norecover.rs:5:12 | LL | const impl Foo { - | ^^^^ expected identifier, found keyword + | ----- ^^^ inherent impl for this type + | | + | const because of this + | + = note: only trait implementations may be annotated with `const` error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-impl-recovery.rs b/tests/ui/traits/const-traits/const-impl-recovery.rs index 0f1c6225d8f0..047fb9866301 100644 --- a/tests/ui/traits/const-traits/const-impl-recovery.rs +++ b/tests/ui/traits/const-traits/const-impl-recovery.rs @@ -1,12 +1,14 @@ #![feature(const_trait_impl)] +//@ check-pass + const trait Foo {} -const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword +const impl Foo for i32 {} const trait Bar {} -const impl Bar for T {} //~ ERROR: expected identifier, found keyword +const impl Bar for T {} const fn still_implements() {} diff --git a/tests/ui/traits/const-traits/const-impl-recovery.stderr b/tests/ui/traits/const-traits/const-impl-recovery.stderr deleted file mode 100644 index 709084c86e0a..000000000000 --- a/tests/ui/traits/const-traits/const-impl-recovery.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: expected identifier, found keyword `impl` - --> $DIR/const-impl-recovery.rs:5:7 - | -LL | const impl Foo for i32 {} - | ^^^^ expected identifier, found keyword - | -help: you might have meant to write a const trait impl - | -LL - const impl Foo for i32 {} -LL + impl const Foo for i32 {} - | - -error: expected identifier, found keyword `impl` - --> $DIR/const-impl-recovery.rs:9:7 - | -LL | const impl Bar for T {} - | ^^^^ expected identifier, found keyword - | -help: you might have meant to write a const trait impl - | -LL - const impl Bar for T {} -LL + impl const Bar for T {} - | - -error: aborting due to 2 previous errors -