parse const closures
This commit is contained in:
parent
56ee65aeb6
commit
4fb10c0ce4
@ -1307,6 +1307,7 @@ pub fn is_approximately_pattern(&self) -> bool {
|
||||
pub struct Closure {
|
||||
pub binder: ClosureBinder,
|
||||
pub capture_clause: CaptureBy,
|
||||
pub constness: Const,
|
||||
pub asyncness: Async,
|
||||
pub movability: Movability,
|
||||
pub fn_decl: P<FnDecl>,
|
||||
|
@ -1362,6 +1362,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause: _,
|
||||
constness,
|
||||
asyncness,
|
||||
movability: _,
|
||||
fn_decl,
|
||||
@ -1370,6 +1371,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
fn_arg_span: _,
|
||||
}) => {
|
||||
vis.visit_closure_binder(binder);
|
||||
visit_constness(constness, vis);
|
||||
vis.visit_asyncness(asyncness);
|
||||
vis.visit_fn_decl(fn_decl);
|
||||
vis.visit_expr(body);
|
||||
|
@ -836,6 +836,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||
binder,
|
||||
capture_clause: _,
|
||||
asyncness: _,
|
||||
constness: _,
|
||||
movability: _,
|
||||
fn_decl,
|
||||
body,
|
||||
|
@ -209,6 +209,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
constness,
|
||||
asyncness,
|
||||
movability,
|
||||
fn_decl,
|
||||
@ -233,6 +234,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
binder,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
*constness,
|
||||
*movability,
|
||||
fn_decl,
|
||||
body,
|
||||
@ -651,6 +653,7 @@ pub(super) fn make_async_expr(
|
||||
fn_decl_span: self.lower_span(span),
|
||||
fn_arg_span: None,
|
||||
movability: Some(hir::Movability::Static),
|
||||
constness: hir::Constness::NotConst,
|
||||
});
|
||||
|
||||
hir::ExprKind::Closure(c)
|
||||
@ -890,6 +893,7 @@ fn lower_expr_closure(
|
||||
binder: &ClosureBinder,
|
||||
capture_clause: CaptureBy,
|
||||
closure_id: NodeId,
|
||||
constness: Const,
|
||||
movability: Movability,
|
||||
decl: &FnDecl,
|
||||
body: &Expr,
|
||||
@ -927,6 +931,7 @@ fn lower_expr_closure(
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: Some(self.lower_span(fn_arg_span)),
|
||||
movability: generator_option,
|
||||
constness: self.lower_constness(constness),
|
||||
});
|
||||
|
||||
hir::ExprKind::Closure(c)
|
||||
@ -1041,6 +1046,7 @@ fn lower_expr_async_closure(
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: Some(self.lower_span(fn_arg_span)),
|
||||
movability: None,
|
||||
constness: hir::Constness::NotConst,
|
||||
});
|
||||
hir::ExprKind::Closure(c)
|
||||
}
|
||||
|
@ -1239,7 +1239,7 @@ fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_constness(&mut self, c: Const) -> hir::Constness {
|
||||
pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
|
||||
match c {
|
||||
Const::Yes(_) => hir::Constness::Const,
|
||||
Const::No => hir::Constness::NotConst,
|
||||
|
@ -399,6 +399,7 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
|
||||
ast::ExprKind::Closure(box ast::Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
constness,
|
||||
asyncness,
|
||||
movability,
|
||||
fn_decl,
|
||||
@ -407,6 +408,7 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
|
||||
fn_arg_span: _,
|
||||
}) => {
|
||||
self.print_closure_binder(binder);
|
||||
self.print_constness(*constness);
|
||||
self.print_movability(*movability);
|
||||
self.print_asyncness(*asyncness);
|
||||
self.print_capture_clause(*capture_clause);
|
||||
|
@ -533,6 +533,7 @@ pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::
|
||||
ast::ExprKind::Closure(Box::new(ast::Closure {
|
||||
binder: ast::ClosureBinder::NotPresent,
|
||||
capture_clause: ast::CaptureBy::Ref,
|
||||
constness: ast::Const::No,
|
||||
asyncness: ast::Async::No,
|
||||
movability: ast::Movability::Movable,
|
||||
fn_decl,
|
||||
|
@ -938,6 +938,7 @@ pub struct Crate<'hir> {
|
||||
pub struct Closure<'hir> {
|
||||
pub def_id: LocalDefId,
|
||||
pub binder: ClosureBinder,
|
||||
pub constness: Constness,
|
||||
pub capture_clause: CaptureBy,
|
||||
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
||||
pub fn_decl: &'hir FnDecl<'hir>,
|
||||
|
@ -742,6 +742,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
|
||||
fn_decl_span: _,
|
||||
fn_arg_span: _,
|
||||
movability: _,
|
||||
constness: _,
|
||||
}) => {
|
||||
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||
visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)
|
||||
|
@ -1464,6 +1464,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
}
|
||||
hir::ExprKind::Closure(&hir::Closure {
|
||||
binder,
|
||||
constness,
|
||||
capture_clause,
|
||||
bound_generic_params,
|
||||
fn_decl,
|
||||
@ -1474,6 +1475,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
def_id: _,
|
||||
}) => {
|
||||
self.print_closure_binder(binder, bound_generic_params);
|
||||
self.print_constness(constness);
|
||||
self.print_capture_clause(capture_clause);
|
||||
|
||||
self.print_closure_params(fn_decl, body);
|
||||
@ -2272,10 +2274,7 @@ pub fn print_ty_fn(
|
||||
}
|
||||
|
||||
pub fn print_fn_header_info(&mut self, header: hir::FnHeader) {
|
||||
match header.constness {
|
||||
hir::Constness::NotConst => {}
|
||||
hir::Constness::Const => self.word_nbsp("const"),
|
||||
}
|
||||
self.print_constness(header.constness);
|
||||
|
||||
match header.asyncness {
|
||||
hir::IsAsync::NotAsync => {}
|
||||
@ -2292,6 +2291,13 @@ pub fn print_fn_header_info(&mut self, header: hir::FnHeader) {
|
||||
self.word("fn")
|
||||
}
|
||||
|
||||
pub fn print_constness(&mut self, s: hir::Constness) {
|
||||
match s {
|
||||
hir::Constness::NotConst => {}
|
||||
hir::Constness::Const => self.word_nbsp("const"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_unsafety(&mut self, s: hir::Unsafety) {
|
||||
match s {
|
||||
hir::Unsafety::Normal => {}
|
||||
|
@ -1325,7 +1325,10 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||
self.parse_array_or_repeat_expr(Delimiter::Bracket)
|
||||
} else if self.check_path() {
|
||||
self.parse_path_start_expr()
|
||||
} else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
|
||||
} else if self.check_keyword(kw::Move)
|
||||
|| self.check_keyword(kw::Static)
|
||||
|| self.check_const_closure()
|
||||
{
|
||||
self.parse_closure_expr()
|
||||
} else if self.eat_keyword(kw::If) {
|
||||
self.parse_if_expr()
|
||||
@ -2065,6 +2068,8 @@ fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||
ClosureBinder::NotPresent
|
||||
};
|
||||
|
||||
let constness = self.parse_constness(Case::Sensitive);
|
||||
|
||||
let movability =
|
||||
if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
|
||||
|
||||
@ -2111,6 +2116,7 @@ fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||
ExprKind::Closure(Box::new(ast::Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
constness,
|
||||
asyncness,
|
||||
movability,
|
||||
fn_decl,
|
||||
|
@ -736,6 +736,16 @@ fn check_const_arg(&mut self) -> bool {
|
||||
self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const)
|
||||
}
|
||||
|
||||
fn check_const_closure(&self) -> bool {
|
||||
self.is_keyword_ahead(0, &[kw::Const])
|
||||
&& self.look_ahead(1, |t| match &t.kind {
|
||||
token::Ident(kw::Move | kw::Static | kw::Async, _)
|
||||
| token::OrOr
|
||||
| token::BinOp(token::Or) => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn check_inline_const(&self, dist: usize) -> bool {
|
||||
self.is_keyword_ahead(dist, &[kw::Const])
|
||||
&& self.look_ahead(dist + 1, |t| match &t.kind {
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
pub(crate) fn rewrite_closure(
|
||||
binder: &ast::ClosureBinder,
|
||||
constness: ast::Const,
|
||||
capture: ast::CaptureBy,
|
||||
is_async: &ast::Async,
|
||||
movability: ast::Movability,
|
||||
@ -38,7 +39,7 @@ pub(crate) fn rewrite_closure(
|
||||
debug!("rewrite_closure {:?}", body);
|
||||
|
||||
let (prefix, extra_offset) = rewrite_closure_fn_decl(
|
||||
binder, capture, is_async, movability, fn_decl, body, span, context, shape,
|
||||
binder, constness, capture, is_async, movability, fn_decl, body, span, context, shape,
|
||||
)?;
|
||||
// 1 = space between `|...|` and body.
|
||||
let body_shape = shape.offset_left(extra_offset)?;
|
||||
@ -230,6 +231,7 @@ fn rewrite_closure_block(
|
||||
// Return type is (prefix, extra_offset)
|
||||
fn rewrite_closure_fn_decl(
|
||||
binder: &ast::ClosureBinder,
|
||||
constness: ast::Const,
|
||||
capture: ast::CaptureBy,
|
||||
asyncness: &ast::Async,
|
||||
movability: ast::Movability,
|
||||
@ -250,6 +252,12 @@ fn rewrite_closure_fn_decl(
|
||||
ast::ClosureBinder::NotPresent => "".to_owned(),
|
||||
};
|
||||
|
||||
let const_ = if matches!(constness, ast::Const::Yes(_)) {
|
||||
"const "
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let immovable = if movability == ast::Movability::Static {
|
||||
"static "
|
||||
} else {
|
||||
@ -264,7 +272,7 @@ fn rewrite_closure_fn_decl(
|
||||
// 4 = "|| {".len(), which is overconservative when the closure consists of
|
||||
// a single expression.
|
||||
let nested_shape = shape
|
||||
.shrink_left(binder.len() + immovable.len() + is_async.len() + mover.len())?
|
||||
.shrink_left(binder.len() + const_.len() + immovable.len() + is_async.len() + mover.len())?
|
||||
.sub_width(4)?;
|
||||
|
||||
// 1 = |
|
||||
@ -302,7 +310,10 @@ fn rewrite_closure_fn_decl(
|
||||
.tactic(tactic)
|
||||
.preserve_newline(true);
|
||||
let list_str = write_list(&item_vec, &fmt)?;
|
||||
let mut prefix = format!("{}{}{}{}|{}|", binder, immovable, is_async, mover, list_str);
|
||||
let mut prefix = format!(
|
||||
"{}{}{}{}{}|{}|",
|
||||
binder, const_, immovable, is_async, mover, list_str
|
||||
);
|
||||
|
||||
if !ret_str.is_empty() {
|
||||
if prefix.contains('\n') {
|
||||
@ -329,6 +340,7 @@ pub(crate) fn rewrite_last_closure(
|
||||
if let ast::ExprKind::Closure(ref closure) = expr.kind {
|
||||
let ast::Closure {
|
||||
ref binder,
|
||||
constness,
|
||||
capture_clause,
|
||||
ref asyncness,
|
||||
movability,
|
||||
@ -349,6 +361,7 @@ pub(crate) fn rewrite_last_closure(
|
||||
};
|
||||
let (prefix, extra_offset) = rewrite_closure_fn_decl(
|
||||
binder,
|
||||
constness,
|
||||
capture_clause,
|
||||
asyncness,
|
||||
movability,
|
||||
|
@ -205,6 +205,7 @@ pub(crate) fn format_expr(
|
||||
}
|
||||
ast::ExprKind::Closure(ref cl) => closures::rewrite_closure(
|
||||
&cl.binder,
|
||||
cl.constness,
|
||||
cl.capture_clause,
|
||||
&cl.asyncness,
|
||||
cl.movability,
|
||||
|
@ -7,6 +7,6 @@ fn main() {
|
||||
enum Foo { Bar }
|
||||
fn foo(x: impl Iterator<Item = Foo>) {
|
||||
for <Foo>::Bar in x {}
|
||||
//~^ ERROR expected one of `move`, `static`, `|`
|
||||
//~^ ERROR expected one of `const`, `move`, `static`, `|`
|
||||
//~^^ ERROR `for<...>` binders for closures are experimental
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `move`, `static`, `|`, or `||`, found `::`
|
||||
error: expected one of `const`, `move`, `static`, `|`, or `||`, found `::`
|
||||
--> $DIR/recover-quantified-closure.rs:9:14
|
||||
|
|
||||
LL | for <Foo>::Bar in x {}
|
||||
| ^^ expected one of `move`, `static`, `|`, or `||`
|
||||
| ^^ expected one of `const`, `move`, `static`, `|`, or `||`
|
||||
|
||||
error[E0658]: `for<...>` binders for closures are experimental
|
||||
--> $DIR/recover-quantified-closure.rs:2:5
|
||||
|
Loading…
Reference in New Issue
Block a user