Less greedily parse [const] bounds

This commit is contained in:
León Orell Valerian Liehr
2025-09-10 21:41:00 +02:00
parent 1558e65c9e
commit f5dad62d4c
2 changed files with 33 additions and 5 deletions

View File

@@ -1015,12 +1015,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)
}
/// Parse a bound.
///
/// ```ebnf
@@ -1199,10 +1205,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();

View File

@@ -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() {}