about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-09-11 16:11:18 +0000
committerbors <bors@rust-lang.org>2025-09-11 16:11:18 +0000
commit67cb8e039bd8df7ca6c38828756cc22ce335724e (patch)
treed56c2e7f35cb341e3af771e2aba92446f8aab03d
parentf946d4d344d85eb2ddbd675cd46cb38a705faccc (diff)
parent58afb55adc1e4b66c39870da5a1b0a11aa129225 (diff)
downloadrust-67cb8e039bd8df7ca6c38828756cc22ce335724e.tar.gz
rust-67cb8e039bd8df7ca6c38828756cc22ce335724e.zip
Auto merge of #146443 - fmease:beta-less-greedy-maybe-const-bounds, r=fmease
[beta] Backport "Less greedily parse `[const]` bounds"

Backport of rust-lang/rust#146422.
Following https://forge.rust-lang.org/release/backporting.html#beta-backporting-in-rust-langrust.

Not part of some hypothetical future backport rollup because we're under time pressure as release procedures will commence very soon: https://forge.rust-lang.org/#current-release-versions, https://forge.rust-lang.org/release/process.html.

cc `@cuviper`
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs13
-rw-r--r--tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs25
2 files changed, 33 insertions, 5 deletions
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 740dd10ea8b..6827a9f23a4 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -951,12 +951,18 @@ impl<'a> Parser<'a> {
             || self.check(exp!(Tilde))
             || self.check_keyword(exp!(For))
             || self.check(exp!(OpenParen))
-            || self.check(exp!(OpenBracket))
+            || self.can_begin_maybe_const_bound()
             || self.check_keyword(exp!(Const))
             || self.check_keyword(exp!(Async))
             || self.check_keyword(exp!(Use))
     }
 
+    fn can_begin_maybe_const_bound(&mut self) -> bool {
+        self.check(exp!(OpenBracket))
+            && self.look_ahead(1, |t| t.is_keyword(kw::Const))
+            && self.look_ahead(2, |t| *t == token::CloseBracket)
+    }
+
     /// Parses a bound according to the grammar:
     /// ```ebnf
     /// BOUND = TY_BOUND | LT_BOUND
@@ -1137,10 +1143,7 @@ impl<'a> Parser<'a> {
             let span = tilde.to(self.prev_token.span);
             self.psess.gated_spans.gate(sym::const_trait_impl, span);
             BoundConstness::Maybe(span)
-        } else if self.check(exp!(OpenBracket))
-            && self.look_ahead(1, |t| t.is_keyword(kw::Const))
-            && self.look_ahead(2, |t| *t == token::CloseBracket)
-        {
+        } else if self.can_begin_maybe_const_bound() {
             let start = self.token.span;
             self.bump();
             self.expect_keyword(exp!(Const)).unwrap();
diff --git a/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs
new file mode 100644
index 00000000000..75077577b8c
--- /dev/null
+++ b/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs
@@ -0,0 +1,25 @@
+// Ensure that we don't consider `[` to begin trait bounds to contain breakages.
+// Only `[const]` in its entirety begins a trait bound.
+// See also test `macro-const-trait-bound-theoretical-regression.rs`.
+
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
+// Setting the edition to >2015 since we didn't regress `check! { dyn [const] Trait }` in Rust 2015.
+// See also test `traits/const-traits/macro-dyn-const-2015.rs`.
+//@ edition:2018
+
+macro_rules! check {
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (dyn [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
+    (impl [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
+}
+
+check!(dyn [T] Trait);
+
+// issue: <https://github.com/rust-lang/rust/issues/146417>
+check!(impl [T] Trait);
+check!(impl [T: Bound] Trait);
+
+fn main() {}