Skip to content

Commit 4fb10c0

Browse files
committed
parse const closures
1 parent 56ee65a commit 4fb10c0

File tree

16 files changed

+63
-12
lines changed

16 files changed

+63
-12
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,7 @@ impl Expr {
13071307
pub struct Closure {
13081308
pub binder: ClosureBinder,
13091309
pub capture_clause: CaptureBy,
1310+
pub constness: Const,
13101311
pub asyncness: Async,
13111312
pub movability: Movability,
13121313
pub fn_decl: P<FnDecl>,

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
13621362
ExprKind::Closure(box Closure {
13631363
binder,
13641364
capture_clause: _,
1365+
constness,
13651366
asyncness,
13661367
movability: _,
13671368
fn_decl,
@@ -1370,6 +1371,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
13701371
fn_arg_span: _,
13711372
}) => {
13721373
vis.visit_closure_binder(binder);
1374+
visit_constness(constness, vis);
13731375
vis.visit_asyncness(asyncness);
13741376
vis.visit_fn_decl(fn_decl);
13751377
vis.visit_expr(body);

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
836836
binder,
837837
capture_clause: _,
838838
asyncness: _,
839+
constness: _,
839840
movability: _,
840841
fn_decl,
841842
body,

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
209209
ExprKind::Closure(box Closure {
210210
binder,
211211
capture_clause,
212+
constness,
212213
asyncness,
213214
movability,
214215
fn_decl,
@@ -233,6 +234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
233234
binder,
234235
*capture_clause,
235236
e.id,
237+
*constness,
236238
*movability,
237239
fn_decl,
238240
body,
@@ -651,6 +653,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
651653
fn_decl_span: self.lower_span(span),
652654
fn_arg_span: None,
653655
movability: Some(hir::Movability::Static),
656+
constness: hir::Constness::NotConst,
654657
});
655658

656659
hir::ExprKind::Closure(c)
@@ -890,6 +893,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
890893
binder: &ClosureBinder,
891894
capture_clause: CaptureBy,
892895
closure_id: NodeId,
896+
constness: Const,
893897
movability: Movability,
894898
decl: &FnDecl,
895899
body: &Expr,
@@ -927,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
927931
fn_decl_span: self.lower_span(fn_decl_span),
928932
fn_arg_span: Some(self.lower_span(fn_arg_span)),
929933
movability: generator_option,
934+
constness: self.lower_constness(constness),
930935
});
931936

932937
hir::ExprKind::Closure(c)
@@ -1041,6 +1046,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10411046
fn_decl_span: self.lower_span(fn_decl_span),
10421047
fn_arg_span: Some(self.lower_span(fn_arg_span)),
10431048
movability: None,
1049+
constness: hir::Constness::NotConst,
10441050
});
10451051
hir::ExprKind::Closure(c)
10461052
}

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12391239
}
12401240
}
12411241

1242-
fn lower_constness(&mut self, c: Const) -> hir::Constness {
1242+
pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
12431243
match c {
12441244
Const::Yes(_) => hir::Constness::Const,
12451245
Const::No => hir::Constness::NotConst,

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ impl<'a> State<'a> {
399399
ast::ExprKind::Closure(box ast::Closure {
400400
binder,
401401
capture_clause,
402+
constness,
402403
asyncness,
403404
movability,
404405
fn_decl,
@@ -407,6 +408,7 @@ impl<'a> State<'a> {
407408
fn_arg_span: _,
408409
}) => {
409410
self.print_closure_binder(binder);
411+
self.print_constness(*constness);
410412
self.print_movability(*movability);
411413
self.print_asyncness(*asyncness);
412414
self.print_capture_clause(*capture_clause);

compiler/rustc_expand/src/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ impl<'a> ExtCtxt<'a> {
533533
ast::ExprKind::Closure(Box::new(ast::Closure {
534534
binder: ast::ClosureBinder::NotPresent,
535535
capture_clause: ast::CaptureBy::Ref,
536+
constness: ast::Const::No,
536537
asyncness: ast::Async::No,
537538
movability: ast::Movability::Movable,
538539
fn_decl,

compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,7 @@ pub struct Crate<'hir> {
938938
pub struct Closure<'hir> {
939939
pub def_id: LocalDefId,
940940
pub binder: ClosureBinder,
941+
pub constness: Constness,
941942
pub capture_clause: CaptureBy,
942943
pub bound_generic_params: &'hir [GenericParam<'hir>],
943944
pub fn_decl: &'hir FnDecl<'hir>,

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
742742
fn_decl_span: _,
743743
fn_arg_span: _,
744744
movability: _,
745+
constness: _,
745746
}) => {
746747
walk_list!(visitor, visit_generic_param, bound_generic_params);
747748
visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,7 @@ impl<'a> State<'a> {
14641464
}
14651465
hir::ExprKind::Closure(&hir::Closure {
14661466
binder,
1467+
constness,
14671468
capture_clause,
14681469
bound_generic_params,
14691470
fn_decl,
@@ -1474,6 +1475,7 @@ impl<'a> State<'a> {
14741475
def_id: _,
14751476
}) => {
14761477
self.print_closure_binder(binder, bound_generic_params);
1478+
self.print_constness(constness);
14771479
self.print_capture_clause(capture_clause);
14781480

14791481
self.print_closure_params(fn_decl, body);
@@ -2272,10 +2274,7 @@ impl<'a> State<'a> {
22722274
}
22732275

22742276
pub fn print_fn_header_info(&mut self, header: hir::FnHeader) {
2275-
match header.constness {
2276-
hir::Constness::NotConst => {}
2277-
hir::Constness::Const => self.word_nbsp("const"),
2278-
}
2277+
self.print_constness(header.constness);
22792278

22802279
match header.asyncness {
22812280
hir::IsAsync::NotAsync => {}
@@ -2292,6 +2291,13 @@ impl<'a> State<'a> {
22922291
self.word("fn")
22932292
}
22942293

2294+
pub fn print_constness(&mut self, s: hir::Constness) {
2295+
match s {
2296+
hir::Constness::NotConst => {}
2297+
hir::Constness::Const => self.word_nbsp("const"),
2298+
}
2299+
}
2300+
22952301
pub fn print_unsafety(&mut self, s: hir::Unsafety) {
22962302
match s {
22972303
hir::Unsafety::Normal => {}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,10 @@ impl<'a> Parser<'a> {
13251325
self.parse_array_or_repeat_expr(Delimiter::Bracket)
13261326
} else if self.check_path() {
13271327
self.parse_path_start_expr()
1328-
} else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
1328+
} else if self.check_keyword(kw::Move)
1329+
|| self.check_keyword(kw::Static)
1330+
|| self.check_const_closure()
1331+
{
13291332
self.parse_closure_expr()
13301333
} else if self.eat_keyword(kw::If) {
13311334
self.parse_if_expr()
@@ -2065,6 +2068,8 @@ impl<'a> Parser<'a> {
20652068
ClosureBinder::NotPresent
20662069
};
20672070

2071+
let constness = self.parse_constness(Case::Sensitive);
2072+
20682073
let movability =
20692074
if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
20702075

@@ -2111,6 +2116,7 @@ impl<'a> Parser<'a> {
21112116
ExprKind::Closure(Box::new(ast::Closure {
21122117
binder,
21132118
capture_clause,
2119+
constness,
21142120
asyncness,
21152121
movability,
21162122
fn_decl,

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,16 @@ impl<'a> Parser<'a> {
736736
self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const)
737737
}
738738

739+
fn check_const_closure(&self) -> bool {
740+
self.is_keyword_ahead(0, &[kw::Const])
741+
&& 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,
745+
_ => false,
746+
})
747+
}
748+
739749
fn check_inline_const(&self, dist: usize) -> bool {
740750
self.is_keyword_ahead(dist, &[kw::Const])
741751
&& self.look_ahead(dist + 1, |t| match &t.kind {

src/tools/rustfmt/src/closures.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt};
2626

2727
pub(crate) fn rewrite_closure(
2828
binder: &ast::ClosureBinder,
29+
constness: ast::Const,
2930
capture: ast::CaptureBy,
3031
is_async: &ast::Async,
3132
movability: ast::Movability,
@@ -38,7 +39,7 @@ pub(crate) fn rewrite_closure(
3839
debug!("rewrite_closure {:?}", body);
3940

4041
let (prefix, extra_offset) = rewrite_closure_fn_decl(
41-
binder, capture, is_async, movability, fn_decl, body, span, context, shape,
42+
binder, constness, capture, is_async, movability, fn_decl, body, span, context, shape,
4243
)?;
4344
// 1 = space between `|...|` and body.
4445
let body_shape = shape.offset_left(extra_offset)?;
@@ -230,6 +231,7 @@ fn rewrite_closure_block(
230231
// Return type is (prefix, extra_offset)
231232
fn rewrite_closure_fn_decl(
232233
binder: &ast::ClosureBinder,
234+
constness: ast::Const,
233235
capture: ast::CaptureBy,
234236
asyncness: &ast::Async,
235237
movability: ast::Movability,
@@ -250,6 +252,12 @@ fn rewrite_closure_fn_decl(
250252
ast::ClosureBinder::NotPresent => "".to_owned(),
251253
};
252254

255+
let const_ = if matches!(constness, ast::Const::Yes(_)) {
256+
"const "
257+
} else {
258+
""
259+
};
260+
253261
let immovable = if movability == ast::Movability::Static {
254262
"static "
255263
} else {
@@ -264,7 +272,7 @@ fn rewrite_closure_fn_decl(
264272
// 4 = "|| {".len(), which is overconservative when the closure consists of
265273
// a single expression.
266274
let nested_shape = shape
267-
.shrink_left(binder.len() + immovable.len() + is_async.len() + mover.len())?
275+
.shrink_left(binder.len() + const_.len() + immovable.len() + is_async.len() + mover.len())?
268276
.sub_width(4)?;
269277

270278
// 1 = |
@@ -302,7 +310,10 @@ fn rewrite_closure_fn_decl(
302310
.tactic(tactic)
303311
.preserve_newline(true);
304312
let list_str = write_list(&item_vec, &fmt)?;
305-
let mut prefix = format!("{}{}{}{}|{}|", binder, immovable, is_async, mover, list_str);
313+
let mut prefix = format!(
314+
"{}{}{}{}{}|{}|",
315+
binder, const_, immovable, is_async, mover, list_str
316+
);
306317

307318
if !ret_str.is_empty() {
308319
if prefix.contains('\n') {
@@ -329,6 +340,7 @@ pub(crate) fn rewrite_last_closure(
329340
if let ast::ExprKind::Closure(ref closure) = expr.kind {
330341
let ast::Closure {
331342
ref binder,
343+
constness,
332344
capture_clause,
333345
ref asyncness,
334346
movability,
@@ -349,6 +361,7 @@ pub(crate) fn rewrite_last_closure(
349361
};
350362
let (prefix, extra_offset) = rewrite_closure_fn_decl(
351363
binder,
364+
constness,
352365
capture_clause,
353366
asyncness,
354367
movability,

src/tools/rustfmt/src/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ pub(crate) fn format_expr(
205205
}
206206
ast::ExprKind::Closure(ref cl) => closures::rewrite_closure(
207207
&cl.binder,
208+
cl.constness,
208209
cl.capture_clause,
209210
&cl.asyncness,
210211
cl.movability,

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

Lines changed: 1 addition & 1 deletion
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 `move`, `static`, `|`
10+
//~^ ERROR expected one of `const`, `move`, `static`, `|`
1111
//~^^ ERROR `for<...>` binders for closures are experimental
1212
}

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

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

77
error[E0658]: `for<...>` binders for closures are experimental
88
--> $DIR/recover-quantified-closure.rs:2:5

0 commit comments

Comments
 (0)