Skip to content

Commit 49772fb

Browse files
committed
syntax: don't fake a block around closures' bodies during parsing.
1 parent da2ce22 commit 49772fb

File tree

16 files changed

+106
-153
lines changed

16 files changed

+106
-153
lines changed

src/librustc/lint/context.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -994,10 +994,10 @@ impl<'a> ast_visit::Visitor for EarlyContext<'a> {
994994
}
995995

996996
fn visit_fn(&mut self, fk: ast_visit::FnKind, decl: &ast::FnDecl,
997-
body: &ast::Block, span: Span, id: ast::NodeId) {
998-
run_lints!(self, check_fn, early_passes, fk, decl, body, span, id);
999-
ast_visit::walk_fn(self, fk, decl, body, span);
1000-
run_lints!(self, check_fn_post, early_passes, fk, decl, body, span, id);
997+
span: Span, id: ast::NodeId) {
998+
run_lints!(self, check_fn, early_passes, fk, decl, span, id);
999+
ast_visit::walk_fn(self, fk, decl, span);
1000+
run_lints!(self, check_fn_post, early_passes, fk, decl, span, id);
10011001
}
10021002

10031003
fn visit_variant_data(&mut self,

src/librustc/lint/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ pub trait EarlyLintPass: LintPass {
200200
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
201201
fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
202202
fn check_fn(&mut self, _: &EarlyContext,
203-
_: ast_visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
203+
_: ast_visit::FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { }
204204
fn check_fn_post(&mut self, _: &EarlyContext,
205-
_: ast_visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
205+
_: ast_visit::FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { }
206206
fn check_trait_item(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
207207
fn check_trait_item_post(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
208208
fn check_impl_item(&mut self, _: &EarlyContext, _: &ast::ImplItem) { }

src/librustc_passes/hir_stats.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,10 @@ impl<'v> ast_visit::Visitor for StatCollector<'v> {
295295
fn visit_fn(&mut self,
296296
fk: ast_visit::FnKind,
297297
fd: &ast::FnDecl,
298-
b: &ast::Block,
299298
s: Span,
300299
_: NodeId) {
301300
self.record("FnDecl", Id::None, fd);
302-
ast_visit::walk_fn(self, fk, fd, b, s)
301+
ast_visit::walk_fn(self, fk, fd, s)
303302
}
304303

305304
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {

src/librustc_resolve/lib.rs

+35-34
Original file line numberDiff line numberDiff line change
@@ -596,21 +596,52 @@ impl<'a> Visitor for Resolver<'a> {
596596
fn visit_fn(&mut self,
597597
function_kind: FnKind,
598598
declaration: &FnDecl,
599-
block: &Block,
600599
_: Span,
601600
node_id: NodeId) {
602601
let rib_kind = match function_kind {
603602
FnKind::ItemFn(_, generics, ..) => {
604603
self.visit_generics(generics);
605604
ItemRibKind
606605
}
607-
FnKind::Method(_, sig, _) => {
606+
FnKind::Method(_, sig, _, _) => {
608607
self.visit_generics(&sig.generics);
609608
MethodRibKind(!sig.decl.has_self())
610609
}
611-
FnKind::Closure => ClosureRibKind(node_id),
610+
FnKind::Closure(_) => ClosureRibKind(node_id),
612611
};
613-
self.resolve_function(rib_kind, declaration, block);
612+
613+
// Create a value rib for the function.
614+
self.value_ribs.push(Rib::new(rib_kind));
615+
616+
// Create a label rib for the function.
617+
self.label_ribs.push(Rib::new(rib_kind));
618+
619+
// Add each argument to the rib.
620+
let mut bindings_list = FxHashMap();
621+
for argument in &declaration.inputs {
622+
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
623+
624+
self.visit_ty(&argument.ty);
625+
626+
debug!("(resolving function) recorded argument");
627+
}
628+
visit::walk_fn_ret_ty(self, &declaration.output);
629+
630+
// Resolve the function body.
631+
match function_kind {
632+
FnKind::ItemFn(.., body) |
633+
FnKind::Method(.., body) => {
634+
self.visit_block(body);
635+
}
636+
FnKind::Closure(body) => {
637+
self.visit_expr(body);
638+
}
639+
};
640+
641+
debug!("(resolving function) leaving function");
642+
643+
self.label_ribs.pop();
644+
self.value_ribs.pop();
614645
}
615646
}
616647

@@ -1856,36 +1887,6 @@ impl<'a> Resolver<'a> {
18561887
self.value_ribs.pop();
18571888
}
18581889

1859-
fn resolve_function(&mut self,
1860-
rib_kind: RibKind<'a>,
1861-
declaration: &FnDecl,
1862-
block: &Block) {
1863-
// Create a value rib for the function.
1864-
self.value_ribs.push(Rib::new(rib_kind));
1865-
1866-
// Create a label rib for the function.
1867-
self.label_ribs.push(Rib::new(rib_kind));
1868-
1869-
// Add each argument to the rib.
1870-
let mut bindings_list = FxHashMap();
1871-
for argument in &declaration.inputs {
1872-
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
1873-
1874-
self.visit_ty(&argument.ty);
1875-
1876-
debug!("(resolving function) recorded argument");
1877-
}
1878-
visit::walk_fn_ret_ty(self, &declaration.output);
1879-
1880-
// Resolve the function body.
1881-
self.visit_block(block);
1882-
1883-
debug!("(resolving function) leaving function");
1884-
1885-
self.label_ribs.pop();
1886-
self.value_ribs.pop();
1887-
}
1888-
18891890
fn resolve_trait_reference(&mut self,
18901891
id: NodeId,
18911892
trait_path: &Path,

src/librustc_save_analysis/dump_visitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
14141414
}
14151415

14161416
// walk the body
1417-
self.nest(ex.id, |v| v.visit_block(&body));
1417+
self.nest(ex.id, |v| v.visit_expr(body));
14181418
}
14191419
ast::ExprKind::ForLoop(ref pattern, ref subexpression, ref block, _) |
14201420
ast::ExprKind::WhileLet(ref pattern, ref subexpression, ref block, _) => {

src/libsyntax/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1017,10 +1017,10 @@ pub enum ExprKind {
10171017
Loop(P<Block>, Option<SpannedIdent>),
10181018
/// A `match` block.
10191019
Match(P<Expr>, Vec<Arm>),
1020-
/// A closure (for example, `move |a, b, c| {a + b + c}`)
1020+
/// A closure (for example, `move |a, b, c| a + b + c`)
10211021
///
10221022
/// The final span is the span of the argument block `|...|`
1023-
Closure(CaptureBy, P<FnDecl>, P<Block>, Span),
1023+
Closure(CaptureBy, P<FnDecl>, P<Expr>, Span),
10241024
/// A block (`{ ... }`)
10251025
Block(P<Block>),
10261026

src/libsyntax/ext/build.rs

+15-30
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,13 @@ pub trait AstBuilder {
198198
fn lambda_fn_decl(&self,
199199
span: Span,
200200
fn_decl: P<ast::FnDecl>,
201-
blk: P<ast::Block>,
201+
body: P<ast::Expr>,
202202
fn_decl_span: Span)
203203
-> P<ast::Expr>;
204204

205-
fn lambda(&self, span: Span, ids: Vec<ast::Ident>, blk: P<ast::Block>) -> P<ast::Expr>;
206-
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr>;
207-
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> P<ast::Expr>;
208-
209-
fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Expr>) -> P<ast::Expr>;
210-
fn lambda_expr_0(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>;
211-
fn lambda_expr_1(&self, span: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr>;
205+
fn lambda(&self, span: Span, ids: Vec<ast::Ident>, body: P<ast::Expr>) -> P<ast::Expr>;
206+
fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr>;
207+
fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr>;
212208

213209
fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident>,
214210
blk: Vec<ast::Stmt>) -> P<ast::Expr>;
@@ -940,19 +936,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
940936
fn lambda_fn_decl(&self,
941937
span: Span,
942938
fn_decl: P<ast::FnDecl>,
943-
blk: P<ast::Block>,
939+
body: P<ast::Expr>,
944940
fn_decl_span: Span) // span of the `|...|` part
945941
-> P<ast::Expr> {
946942
self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref,
947943
fn_decl,
948-
blk,
944+
body,
949945
fn_decl_span))
950946
}
951947

952948
fn lambda(&self,
953949
span: Span,
954950
ids: Vec<ast::Ident>,
955-
blk: P<ast::Block>)
951+
body: P<ast::Expr>)
956952
-> P<ast::Expr> {
957953
let fn_decl = self.fn_decl(
958954
ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
@@ -962,41 +958,30 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
962958
// part of the lambda, but it probably (maybe?) corresponds to
963959
// the entire lambda body. Probably we should extend the API
964960
// here, but that's not entirely clear.
965-
self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk, span))
966-
}
967-
968-
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr> {
969-
self.lambda(span, Vec::new(), blk)
961+
self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, body, span))
970962
}
971963

972-
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> P<ast::Expr> {
973-
self.lambda(span, vec![ident], blk)
964+
fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> {
965+
self.lambda(span, Vec::new(), body)
974966
}
975967

976-
fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident>,
977-
expr: P<ast::Expr>) -> P<ast::Expr> {
978-
self.lambda(span, ids, self.block_expr(expr))
979-
}
980-
fn lambda_expr_0(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
981-
self.lambda0(span, self.block_expr(expr))
982-
}
983-
fn lambda_expr_1(&self, span: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> {
984-
self.lambda1(span, self.block_expr(expr), ident)
968+
fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> {
969+
self.lambda(span, vec![ident], body)
985970
}
986971

987972
fn lambda_stmts(&self,
988973
span: Span,
989974
ids: Vec<ast::Ident>,
990975
stmts: Vec<ast::Stmt>)
991976
-> P<ast::Expr> {
992-
self.lambda(span, ids, self.block(span, stmts))
977+
self.lambda(span, ids, self.expr_block(self.block(span, stmts)))
993978
}
994979
fn lambda_stmts_0(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Expr> {
995-
self.lambda0(span, self.block(span, stmts))
980+
self.lambda0(span, self.expr_block(self.block(span, stmts)))
996981
}
997982
fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>,
998983
ident: ast::Ident) -> P<ast::Expr> {
999-
self.lambda1(span, self.block(span, stmts), ident)
984+
self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
1000985
}
1001986

1002987
fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {

src/libsyntax/feature_gate.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1228,12 +1228,11 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
12281228
fn visit_fn(&mut self,
12291229
fn_kind: FnKind,
12301230
fn_decl: &ast::FnDecl,
1231-
block: &ast::Block,
12321231
span: Span,
12331232
_node_id: NodeId) {
12341233
// check for const fn declarations
12351234
match fn_kind {
1236-
FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _) => {
1235+
FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) => {
12371236
gate_feature_post!(&self, const_fn, span, "const fn is unstable");
12381237
}
12391238
_ => {
@@ -1245,13 +1244,13 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
12451244
}
12461245

12471246
match fn_kind {
1248-
FnKind::ItemFn(_, _, _, _, abi, _) |
1249-
FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => {
1247+
FnKind::ItemFn(_, _, _, _, abi, _, _) |
1248+
FnKind::Method(_, &ast::MethodSig { abi, .. }, _, _) => {
12501249
self.check_abi(abi, span);
12511250
}
12521251
_ => {}
12531252
}
1254-
visit::walk_fn(self, fn_kind, fn_decl, block, span);
1253+
visit::walk_fn(self, fn_kind, fn_decl, span);
12551254
}
12561255

12571256
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {

src/libsyntax/fold.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
12011201
ExprKind::Closure(capture_clause, decl, body, span) => {
12021202
ExprKind::Closure(capture_clause,
12031203
folder.fold_fn_decl(decl),
1204-
folder.fold_block(body),
1204+
folder.fold_expr(body),
12051205
folder.new_span(span))
12061206
}
12071207
ExprKind::Block(blk) => ExprKind::Block(folder.fold_block(blk)),

src/libsyntax/parse/parser.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -3162,25 +3162,12 @@ impl<'a> Parser<'a> {
31623162
let decl = self.parse_fn_block_decl()?;
31633163
let decl_hi = self.prev_span.hi;
31643164
let body = match decl.output {
3165-
FunctionRetTy::Default(_) => {
3166-
// If no explicit return type is given, parse any
3167-
// expr and wrap it up in a dummy block:
3168-
let body_expr = self.parse_expr()?;
3169-
P(ast::Block {
3170-
id: ast::DUMMY_NODE_ID,
3171-
span: body_expr.span,
3172-
stmts: vec![Stmt {
3173-
span: body_expr.span,
3174-
node: StmtKind::Expr(body_expr),
3175-
id: ast::DUMMY_NODE_ID,
3176-
}],
3177-
rules: BlockCheckMode::Default,
3178-
})
3179-
}
3165+
FunctionRetTy::Default(_) => self.parse_expr()?,
31803166
_ => {
31813167
// If an explicit return type is given, require a
31823168
// block to appear (RFC 968).
3183-
self.parse_block()?
3169+
let body_lo = self.span.lo;
3170+
self.parse_block_expr(body_lo, BlockCheckMode::Default, ThinVec::new())?
31843171
}
31853172
};
31863173

src/libsyntax/print/pprust.rs

+2-20
Original file line numberDiff line numberDiff line change
@@ -2128,26 +2128,8 @@ impl<'a> State<'a> {
21282128

21292129
try!(self.print_fn_block_args(&decl));
21302130
try!(space(&mut self.s));
2131-
2132-
let default_return = match decl.output {
2133-
ast::FunctionRetTy::Default(..) => true,
2134-
_ => false
2135-
};
2136-
2137-
match body.stmts.last().map(|stmt| &stmt.node) {
2138-
Some(&ast::StmtKind::Expr(ref i_expr)) if default_return &&
2139-
body.stmts.len() == 1 => {
2140-
// we extract the block, so as not to create another set of boxes
2141-
if let ast::ExprKind::Block(ref blk) = i_expr.node {
2142-
try!(self.print_block_unclosed_with_attrs(&blk, &i_expr.attrs));
2143-
} else {
2144-
// this is a bare expression
2145-
try!(self.print_expr(&i_expr));
2146-
try!(self.end()); // need to close a box
2147-
}
2148-
}
2149-
_ => try!(self.print_block_unclosed(&body)),
2150-
}
2131+
try!(self.print_expr(body));
2132+
try!(self.end()); // need to close a box
21512133

21522134
// a box will be closed by print_expr, but we didn't want an overall
21532135
// wrapper so we closed the corresponding opening. so create an

src/libsyntax/util/node_count.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ impl Visitor for NodeCounter {
7575
self.count += 1;
7676
walk_generics(self, g)
7777
}
78-
fn visit_fn(&mut self, fk: FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
78+
fn visit_fn(&mut self, fk: FnKind, fd: &FnDecl, s: Span, _: NodeId) {
7979
self.count += 1;
80-
walk_fn(self, fk, fd, b, s)
80+
walk_fn(self, fk, fd, s)
8181
}
8282
fn visit_trait_item(&mut self, ti: &TraitItem) {
8383
self.count += 1;

0 commit comments

Comments
 (0)