diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs index a6ff716488526..1c27e7c53f914 100644 --- a/src/librustc/hir/fold.rs +++ b/src/librustc/hir/fold.rs @@ -1060,10 +1060,11 @@ pub fn noop_fold_expr(Expr { id, node, span, attrs }: Expr, folder: & arms.move_map(|x| folder.fold_arm(x)), source) } - ExprClosure(capture_clause, decl, body) => { + ExprClosure(capture_clause, decl, body, fn_decl_span) => { ExprClosure(capture_clause, folder.fold_fn_decl(decl), - folder.fold_block(body)) + folder.fold_block(body), + folder.new_span(fn_decl_span)) } ExprBlock(blk) => ExprBlock(folder.fold_block(blk)), ExprAssign(el, er) => { diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 6e6f845abd368..ec9b465521b97 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -785,7 +785,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprClosure(_, ref function_declaration, ref body) => { + ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => { visitor.visit_fn(FnKind::Closure(expression.attrs.as_attr_slice()), function_declaration, body, diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0a01cc91f0e30..6f30553e26638 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1260,11 +1260,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { arms.iter().map(|x| lower_arm(lctx, x)).collect(), hir::MatchSource::Normal) } - ExprKind::Closure(capture_clause, ref decl, ref body) => { + ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { lctx.with_parent_def(e.id, || { hir::ExprClosure(lower_capture_clause(lctx, capture_clause), lower_fn_decl(lctx, decl), - lower_block(lctx, body)) + lower_block(lctx, body), + fn_decl_span) }) } ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 8c626226bd3c3..4af37fe16adb1 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -250,7 +250,7 @@ impl<'a> FnLikeNode<'a> { } } map::NodeExpr(e) => match e.node { - ast::ExprClosure(_, ref decl, ref block) => + ast::ExprClosure(_, ref decl, ref block, _fn_decl_span) => closure(ClosureParts::new(&decl, &block, e.id, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 4e7520035238f..7eaace91ae9b6 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -949,8 +949,10 @@ pub enum Expr_ { /// A `match` block, with a source that indicates whether or not it is /// the result of a desugaring, and if so, which kind. ExprMatch(P, HirVec, MatchSource), - /// A closure (for example, `move |a, b, c| {a + b + c}`) - ExprClosure(CaptureClause, P, P), + /// A closure (for example, `move |a, b, c| {a + b + c}`). + /// + /// The final span is the span of the argument block `|...|` + ExprClosure(CaptureClause, P, P, Span), /// A block (`{ ... }`) ExprBlock(P), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index e595c619e859b..8335ce3c736b8 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1392,7 +1392,7 @@ impl<'a> State<'a> { } self.bclose_(expr.span, indent_unit)?; } - hir::ExprClosure(capture_clause, ref decl, ref body) => { + hir::ExprClosure(capture_clause, ref decl, ref body, _fn_decl_span) => { self.print_capture_clause(capture_clause)?; self.print_fn_block_args(&decl)?; diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c4d6f100671b0..002f202796cef 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -537,8 +537,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { self.consume_expr(&count); } - hir::ExprClosure(..) => { - self.walk_captures(expr) + hir::ExprClosure(_, _, _, fn_decl_span) => { + self.walk_captures(expr, fn_decl_span) } hir::ExprBox(ref base) => { @@ -1142,7 +1142,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { })); } - fn walk_captures(&mut self, closure_expr: &hir::Expr) { + fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) { debug!("walk_captures({:?})", closure_expr); self.tcx().with_freevars(closure_expr.id, |freevars| { @@ -1152,7 +1152,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { closure_expr_id: closure_expr.id }; let upvar_capture = self.typer.upvar_capture(upvar_id).unwrap(); let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id, - closure_expr.span, + fn_decl_span, freevar.def)); match upvar_capture { ty::UpvarCapture::ByValue => { @@ -1161,7 +1161,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } ty::UpvarCapture::ByRef(upvar_borrow) => { self.delegate.borrow(closure_expr.id, - closure_expr.span, + fn_decl_span, cmt_var, upvar_borrow.region, upvar_borrow.kind, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 35991ae56c8a1..ff20d41ce9dc4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -948,7 +948,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&e, succ) } - hir::ExprClosure(_, _, ref blk) => { + hir::ExprClosure(_, _, ref blk, _) => { debug!("{} is an ExprClosure", expr_to_string(expr)); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 2f77552c389ad..7b31cd815677e 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -728,7 +728,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> { }; match fn_expr.node { - hir::ExprClosure(_, _, ref body) => body.id, + hir::ExprClosure(_, _, ref body, _) => body.id, _ => bug!() } }; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index d7c928b8d6e1f..15db356b1ba95 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -415,7 +415,7 @@ pub fn closure_to_block(closure_id: ast::NodeId, tcx: &TyCtxt) -> ast::NodeId { match tcx.map.get(closure_id) { hir_map::NodeExpr(expr) => match expr.node { - hir::ExprClosure(_, _, ref block) => { + hir::ExprClosure(_, _, ref block, _) => { block.id } _ => { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 12dcb32da3fcd..7dab8c4c5fb2a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -725,7 +725,7 @@ fn convert_var<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, let body_id = match cx.tcx.map.find(closure_expr_id) { Some(map::NodeExpr(expr)) => { match expr.node { - hir::ExprClosure(_, _, ref body) => body.id, + hir::ExprClosure(_, _, ref body, _) => body.id, _ => { span_bug!(expr.span, "closure expr is not a closure expr"); } diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 9a58a704c52cc..2174d1cf9b82a 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -48,7 +48,7 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> { hir::ExprLoop(ref b, _) => { self.with_context(Loop, |v| v.visit_block(&b)); } - hir::ExprClosure(_, _, ref b) => { + hir::ExprClosure(_, _, ref b, _) => { self.with_context(Closure, |v| v.visit_block(&b)); } hir::ExprBreak(_) => self.require_loop("break", e.span), diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index bf6ad7039636e..e96be4714d0ee 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1258,7 +1258,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, ty), } } - ast::ExprKind::Closure(_, ref decl, ref body) => { + ast::ExprKind::Closure(_, ref decl, ref body, _fn_decl_span) => { let mut id = String::from("$"); id.push_str(&ex.id.to_string()); self.process_formals(&decl.inputs, &id); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index cea67f46db527..9190389b722b6 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1339,7 +1339,7 @@ fn build_cfg(tcx: &TyCtxt, id: ast::NodeId) -> (ast::NodeId, Option) { } Some(hir_map::NodeExpr(e)) => { match e.node { - hir::ExprClosure(_, _, ref blk) => blk, + hir::ExprClosure(_, _, ref blk, _) => blk, _ => bug!("unexpected expr variant in has_nested_returns"), } } diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 89f3b295c8d22..b9af0bbe3d123 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -990,7 +990,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, None => C_nil(cx), } }, - hir::ExprClosure(_, ref decl, ref body) => { + hir::ExprClosure(_, ref decl, ref body, _) => { match ety.sty { ty::TyClosure(def_id, ref substs) => { closure::trans_closure_expr(closure::Dest::Ignore(cx), diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index 4b1292e4086f7..3a8974c2aca03 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -479,7 +479,7 @@ fn walk_expr(cx: &CrateContext, }) } - hir::ExprClosure(_, ref decl, ref block) => { + hir::ExprClosure(_, ref decl, ref block, _) => { with_new_scope(cx, block.span, scope_stack, diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index 6955d51ceccaf..cd11ca586890c 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -1118,7 +1118,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, hir::ExprVec(..) | hir::ExprRepeat(..) => { tvec::trans_fixed_vstore(bcx, expr, dest) } - hir::ExprClosure(_, ref decl, ref body) => { + hir::ExprClosure(_, ref decl, ref body, _) => { let dest = match dest { SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest), Ignore => closure::Dest::Ignore(bcx.ccx()) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 67b91f7838c66..d187f82c59644 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3530,7 +3530,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, hir::ExprMatch(ref discrim, ref arms, match_src) => { _match::check_match(fcx, expr, &discrim, arms, expected, match_src); } - hir::ExprClosure(capture, ref decl, ref body) => { + hir::ExprClosure(capture, ref decl, ref body, _) => { closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected); } hir::ExprBlock(ref b) => { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 2a4de6e091b3d..5efd57c4d1fc9 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -782,7 +782,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { intravisit::walk_expr(rcx, expr); } - hir::ExprClosure(_, _, ref body) => { + hir::ExprClosure(_, _, ref body, _) => { check_expr_fn_block(rcx, expr, &body); } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 40481cda76290..c39e992eb3642 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -98,7 +98,7 @@ struct SeedBorrowKind<'a,'tcx:'a> { impl<'a, 'tcx, 'v> Visitor<'v> for SeedBorrowKind<'a, 'tcx> { fn visit_expr(&mut self, expr: &hir::Expr) { match expr.node { - hir::ExprClosure(cc, _, ref body) => { + hir::ExprClosure(cc, _, ref body, _) => { self.check_closure(expr, cc, &body); } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 68327ccd39ab6..ad78740921cbc 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -156,7 +156,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { self.visit_method_map_entry(ResolvingExpr(e.span), MethodCall::expr(e.id)); - if let hir::ExprClosure(_, ref decl, _) = e.node { + if let hir::ExprClosure(_, ref decl, _, _) = e.node { for input in &decl.inputs { self.visit_node_id(ResolvingExpr(e.span), input.id); } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index c20270e830665..70b3edac5c5dc 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -830,7 +830,7 @@ impl HashMap /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { + pub fn keys(&self) -> Keys { Keys { inner: self.iter() } } @@ -852,7 +852,7 @@ impl HashMap /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn values<'a>(&'a self) -> Values<'a, K, V> { + pub fn values(&self) -> Values { Values { inner: self.iter() } } @@ -880,7 +880,7 @@ impl HashMap /// } /// ``` #[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")] - pub fn values_mut<'a>(&'a mut self) -> ValuesMut<'a, K, V> { + pub fn values_mut<'a>(&'a mut self) -> ValuesMut { ValuesMut { inner: self.iter_mut() } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index df9f935446d71..dc59d47528610 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -986,7 +986,9 @@ pub enum ExprKind { /// A `match` block. Match(P, Vec), /// A closure (for example, `move |a, b, c| {a + b + c}`) - Closure(CaptureBy, P, P), + /// + /// The final span is the span of the argument block `|...|` + Closure(CaptureBy, P, P, Span), /// A block (`{ ... }`) Block(P), diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index a4e5b68277d69..8ebf4863af5fa 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -194,10 +194,14 @@ pub trait AstBuilder { cond: P, then: P, els: Option>) -> P; fn expr_loop(&self, span: Span, block: P) -> P; - fn lambda_fn_decl(&self, span: Span, - fn_decl: P, blk: P) -> P; + fn lambda_fn_decl(&self, + span: Span, + fn_decl: P, + blk: P, + fn_decl_span: Span) + -> P; - fn lambda(&self, span: Span, ids: Vec , blk: P) -> P; + fn lambda(&self, span: Span, ids: Vec, blk: P) -> P; fn lambda0(&self, span: Span, blk: P) -> P; fn lambda1(&self, span: Span, blk: P, ident: ast::Ident) -> P; @@ -894,17 +898,34 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr(span, ast::ExprKind::Loop(block, None)) } - fn lambda_fn_decl(&self, span: Span, - fn_decl: P, blk: P) -> P { - self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk)) + fn lambda_fn_decl(&self, + span: Span, + fn_decl: P, + blk: P, + fn_decl_span: Span) // span of the `|...|` part + -> P { + self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, + fn_decl, + blk, + fn_decl_span)) } - fn lambda(&self, span: Span, ids: Vec, blk: P) -> P { + + fn lambda(&self, + span: Span, + ids: Vec, + blk: P) + -> P { let fn_decl = self.fn_decl( ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), self.ty_infer(span)); - self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk)) + // FIXME -- We are using `span` as the span of the `|...|` + // part of the lambda, but it probably (maybe?) corresponds to + // the entire lambda body. Probably we should extend the API + // here, but that's not entirely clear. + self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, blk, span)) } + fn lambda0(&self, span: Span, blk: P) -> P { self.lambda(span, Vec::new(), blk) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index cd7b0fcfb0044..38132eb42ee80 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -149,14 +149,17 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { fld.cx.expr(span, il).with_attrs(fold_thin_attrs(attrs, fld)) } - ast::ExprKind::Closure(capture_clause, fn_decl, block) => { + ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => { let (rewritten_fn_decl, rewritten_block) = expand_and_rename_fn_decl_and_block(fn_decl, block, fld); let new_node = ast::ExprKind::Closure(capture_clause, - rewritten_fn_decl, - rewritten_block); - P(ast::Expr{id:id, node: new_node, span: fld.new_span(span), - attrs: fold_thin_attrs(attrs, fld)}) + rewritten_fn_decl, + rewritten_block, + fld.new_span(fn_decl_span)); + P(ast::Expr{ id:id, + node: new_node, + span: fld.new_span(span), + attrs: fold_thin_attrs(attrs, fld) }) } _ => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 89451e795503f..3f788a52d2b39 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1241,10 +1241,11 @@ pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mu ExprKind::Match(folder.fold_expr(expr), arms.move_map(|x| folder.fold_arm(x))) } - ExprKind::Closure(capture_clause, decl, body) => { + ExprKind::Closure(capture_clause, decl, body, span) => { ExprKind::Closure(capture_clause, - folder.fold_fn_decl(decl), - folder.fold_block(body)) + folder.fold_fn_decl(decl), + folder.fold_block(body), + folder.new_span(span)) } ExprKind::Block(blk) => ExprKind::Block(folder.fold_block(blk)), ExprKind::Assign(el, er) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f3d3bbd9f9905..a4284d0b6742f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3225,13 +3225,15 @@ impl<'a> Parser<'a> { Ok(self.mk_expr(lo, hi, ExprKind::IfLet(pat, expr, thn, els), attrs)) } - // `|args| expr` - pub fn parse_lambda_expr(&mut self, lo: BytePos, + // `move |args| expr` + pub fn parse_lambda_expr(&mut self, + lo: BytePos, capture_clause: CaptureBy, attrs: ThinAttributes) -> PResult<'a, P> { let decl = self.parse_fn_block_decl()?; + let decl_hi = self.last_span.hi; let body = match decl.output { FunctionRetTy::Default(_) => { // If no explicit return type is given, parse any @@ -3255,7 +3257,8 @@ impl<'a> Parser<'a> { Ok(self.mk_expr( lo, body.span.hi, - ExprKind::Closure(capture_clause, decl, body), attrs)) + ExprKind::Closure(capture_clause, decl, body, mk_sp(lo, decl_hi)), + attrs)) } // `else` token already eaten diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 95f1b63168b47..d266866987535 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2086,7 +2086,7 @@ impl<'a> State<'a> { } self.bclose_(expr.span, INDENT_UNIT)?; } - ast::ExprKind::Closure(capture_clause, ref decl, ref body) => { + ast::ExprKind::Closure(capture_clause, ref decl, ref body, _) => { self.print_capture_clause(capture_clause)?; self.print_fn_block_args(&decl)?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 413017c727177..f50a480e5e55a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -743,7 +743,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprKind::Closure(_, ref function_declaration, ref body) => { + ExprKind::Closure(_, ref function_declaration, ref body, _decl_span) => { visitor.visit_fn(FnKind::Closure, function_declaration, body,