Skip to content

Commit d9981f8

Browse files
committed
Less greedily parse [const] bounds
1 parent ff0cf11 commit d9981f8

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,12 +1015,18 @@ impl<'a> Parser<'a> {
10151015
|| self.check(exp!(Tilde))
10161016
|| self.check_keyword(exp!(For))
10171017
|| self.check(exp!(OpenParen))
1018-
|| self.check(exp!(OpenBracket))
1018+
|| self.can_begin_maybe_const_bound()
10191019
|| self.check_keyword(exp!(Const))
10201020
|| self.check_keyword(exp!(Async))
10211021
|| self.check_keyword(exp!(Use))
10221022
}
10231023

1024+
fn can_begin_maybe_const_bound(&mut self) -> bool {
1025+
self.check(exp!(OpenBracket))
1026+
&& self.look_ahead(1, |t| t.is_keyword(kw::Const))
1027+
&& self.look_ahead(2, |t| *t == token::CloseBracket)
1028+
}
1029+
10241030
/// Parse a bound.
10251031
///
10261032
/// ```ebnf
@@ -1199,10 +1205,7 @@ impl<'a> Parser<'a> {
11991205
let span = tilde.to(self.prev_token.span);
12001206
self.psess.gated_spans.gate(sym::const_trait_impl, span);
12011207
BoundConstness::Maybe(span)
1202-
} else if self.check(exp!(OpenBracket))
1203-
&& self.look_ahead(1, |t| t.is_keyword(kw::Const))
1204-
&& self.look_ahead(2, |t| *t == token::CloseBracket)
1205-
{
1208+
} else if self.can_begin_maybe_const_bound() {
12061209
let start = self.token.span;
12071210
self.bump();
12081211
self.expect_keyword(exp!(Const)).unwrap();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Ensure that we don't consider `[` to begin trait bounds to contain breakages.
2+
// Only `[const]` in its entirety begins a trait bound.
3+
// See also test `macro-const-trait-bound-theoretical-regression.rs`.
4+
5+
//@ check-pass (KEEP THIS AS A PASSING TEST!)
6+
// Setting the edition to >2015 since we didn't regress `check! { dyn [const] Trait }` in Rust 2015.
7+
// See also test `traits/const-traits/macro-dyn-const-2015.rs`.
8+
//@ edition:2018
9+
10+
macro_rules! check {
11+
($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
12+
13+
// DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
14+
15+
(dyn [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
16+
(impl [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
17+
}
18+
19+
check!(dyn [T] Trait);
20+
21+
// issue: <https://github.com/rust-lang/rust/issues/146417>
22+
check!(impl [T] Trait);
23+
check!(impl [T: Bound] Trait);
24+
25+
fn main() {}

0 commit comments

Comments
 (0)