Skip to content

Commit 679dde7

Browse files
committed
fix parser mistaking const closures for const item
1 parent ad8e1dc commit 679dde7

File tree

5 files changed

+30
-9
lines changed

5 files changed

+30
-9
lines changed

compiler/rustc_parse/src/parser/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ impl<'a> Parser<'a> {
21082108
ClosureBinder::NotPresent
21092109
};
21102110

2111-
let constness = self.parse_constness(Case::Sensitive);
2111+
let constness = self.parse_closure_constness(Case::Sensitive);
21122112

21132113
let movability =
21142114
if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };

compiler/rustc_parse/src/parser/mod.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,10 @@ impl<'a> Parser<'a> {
739739
fn check_const_closure(&self) -> bool {
740740
self.is_keyword_ahead(0, &[kw::Const])
741741
&& self.look_ahead(1, |t| match &t.kind {
742-
token::Ident(kw::Move | kw::Static | kw::Async, _)
743-
| token::OrOr
744-
| token::BinOp(token::Or) => true,
742+
// async closures do not work with const closures, so we do not parse that here.
743+
token::Ident(kw::Move | kw::Static, _) | token::OrOr | token::BinOp(token::Or) => {
744+
true
745+
}
745746
_ => false,
746747
})
747748
}
@@ -1203,8 +1204,18 @@ impl<'a> Parser<'a> {
12031204

12041205
/// Parses constness: `const` or nothing.
12051206
fn parse_constness(&mut self, case: Case) -> Const {
1206-
// Avoid const blocks to be parsed as const items
1207-
if self.look_ahead(1, |t| t != &token::OpenDelim(Delimiter::Brace))
1207+
self.parse_constness_(case, false)
1208+
}
1209+
1210+
/// Parses constness for closures
1211+
fn parse_closure_constness(&mut self, case: Case) -> Const {
1212+
self.parse_constness_(case, true)
1213+
}
1214+
1215+
fn parse_constness_(&mut self, case: Case, is_closure: bool) -> Const {
1216+
// Avoid const blocks and const closures to be parsed as const items
1217+
if (self.check_const_closure() == is_closure)
1218+
&& self.look_ahead(1, |t| t != &token::OpenDelim(Delimiter::Brace))
12081219
&& self.eat_keyword_case(kw::Const, case)
12091220
{
12101221
Const::Yes(self.prev_token.uninterpolated_span())

tests/ui/parser/recover-quantified-closure.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ fn main() {
77
enum Foo { Bar }
88
fn foo(x: impl Iterator<Item = Foo>) {
99
for <Foo>::Bar in x {}
10-
//~^ ERROR expected one of `const`, `move`, `static`, `|`
10+
//~^ ERROR expected one of `move`, `static`, `|`
1111
//~^^ ERROR `for<...>` binders for closures are experimental
1212
}

tests/ui/parser/recover-quantified-closure.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: expected one of `const`, `move`, `static`, `|`, or `||`, found `::`
1+
error: expected one of `move`, `static`, `|`, or `||`, found `::`
22
--> $DIR/recover-quantified-closure.rs:9:14
33
|
44
LL | for <Foo>::Bar in x {}
5-
| ^^ expected one of `const`, `move`, `static`, `|`, or `||`
5+
| ^^ expected one of `move`, `static`, `|`, or `||`
66

77
error[E0658]: `for<...>` binders for closures are experimental
88
--> $DIR/recover-quantified-closure.rs:2:5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
3+
#![feature(const_trait_impl, const_closures)]
4+
#![allow(incomplete_features)]
5+
6+
const fn test() -> impl ~const Fn() {
7+
const move || {}
8+
}
9+
10+
fn main() {}

0 commit comments

Comments
 (0)