diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index faf97f5808e3..a4d222d24cac 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -198,8 +198,8 @@ pub fn visit_all_items_in_krate<'tcx,V,F>(tcx: &ty::ctxt<'tcx>, fn visit_item(&mut self, i: &'tcx hir::Item) { let item_def_id = self.tcx.map.local_def_id(i.id); let task_id = (self.dep_node_fn)(item_def_id); - debug!("About to start task {:?}", task_id); let _task = self.tcx.dep_graph.in_task(task_id); + debug!("Started task {:?}", task_id); self.tcx.dep_graph.read(DepNode::Hir(item_def_id)); self.visitor.visit_item(i) } diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 12b9130b48c6..7d8a35165d28 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -21,14 +21,70 @@ impl<'a,'tcx> Builder<'a,'tcx> { -> BlockAnd<()> { let Block { extent, span, stmts, expr } = self.hir.mirror(ast_block); self.in_scope(extent, block, move |this| { - unpack!(block = this.stmts(block, stmts)); - match expr { - Some(expr) => this.into(destination, block, expr), - None => { - this.cfg.push_assign_unit(block, span, destination); - block.unit() + // This convoluted structure is to avoid using recursion as we walk down a list + // of statements. Basically, the structure we get back is something like: + // + // let x = in { + // expr1; + // let y = in { + // expr2; + // expr3; + // ... + // } + // } + // + // The let bindings are valid till the end of block so all we have to do is to pop all + // the let-scopes at the end. + // + // First we build all the statements in the block. + let mut let_extent_stack = Vec::with_capacity(8); + for stmt in stmts { + let Stmt { span: _, kind } = this.hir.mirror(stmt); + match kind { + StmtKind::Expr { scope, expr } => { + unpack!(block = this.in_scope(scope, block, |this| { + let expr = this.hir.mirror(expr); + let temp = this.temp(expr.ty.clone()); + unpack!(block = this.into(&temp, block, expr)); + unpack!(block = this.build_drop(block, temp)); + block.unit() + })); + } + StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => { + this.push_scope(remainder_scope); + let_extent_stack.push(remainder_scope); + unpack!(block = this.in_scope(init_scope, block, move |this| { + // FIXME #30046 ^~~~ + match initializer { + Some(initializer) => { + this.expr_into_pattern(block, + remainder_scope, + pattern, + initializer) + } + None => { + this.declare_bindings(remainder_scope, &pattern); + block.unit() + } + } + })); + } } } + // Then, the block may have an optional trailing expression which is a “return” value + // of the block. + if let Some(expr) = expr { + unpack!(block = this.into(destination, block, expr)); + } else { + // FIXME(#31472) + this.cfg.push_assign_unit(block, span, destination); + } + // Finally, we pop all the let scopes before exiting out from the scope of block + // itself. + for extent in let_extent_stack.into_iter().rev() { + unpack!(block = this.pop_scope(extent, block)); + } + block.unit() }) } } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index b83d0f6a9803..5d9f827984e0 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -185,4 +185,3 @@ mod into; mod matches; mod misc; mod scope; -mod stmt; diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 7be70867796f..a738663bf8cc 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -249,6 +249,7 @@ impl<'a,'tcx> Builder<'a,'tcx> { extent: CodeExtent, mut block: BasicBlock, target: BasicBlock) { + debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target); let scope_count = 1 + self.scopes.iter().rev().position(|scope| scope.extent == extent) .unwrap_or_else(||{ self.hir.span_bug(span, &format!("extent {:?} does not enclose", extent)) diff --git a/src/librustc_mir/build/stmt.rs b/src/librustc_mir/build/stmt.rs deleted file mode 100644 index 6c0f1c7081be..000000000000 --- a/src/librustc_mir/build/stmt.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use build::{BlockAnd, BlockAndExtension, Builder}; -use hair::*; -use rustc::mir::repr::*; - -impl<'a,'tcx> Builder<'a,'tcx> { - pub fn stmts(&mut self, mut block: BasicBlock, stmts: Vec>) -> BlockAnd<()> { - // This convoluted structure is to avoid using recursion as we walk down a list - // of statements. Basically, the structure we get back is something like: - // - // let x = in { - // let y = in { - // expr1; - // expr2; - // } - // } - // - // To process this, we keep a stack of (Option, - // vec::IntoIter) pairs. At each point we pull off the - // top most pair and extract one statement from the - // iterator. Once it's complete, we pop the scope from the - // first half the pair. - let this = self; - let mut stmt_lists = vec![(None, stmts.into_iter())]; - while !stmt_lists.is_empty() { - let stmt = { - let &mut (_, ref mut stmts) = stmt_lists.last_mut().unwrap(); - stmts.next() - }; - - let stmt = match stmt { - Some(stmt) => stmt, - None => { - let (extent, _) = stmt_lists.pop().unwrap(); - if let Some(extent) = extent { - unpack!(block = this.pop_scope(extent, block)); - } - continue - } - }; - - let Stmt { span: _, kind } = this.hir.mirror(stmt); - match kind { - StmtKind::Let { remainder_scope, init_scope, pattern, initializer, stmts } => { - this.push_scope(remainder_scope); - stmt_lists.push((Some(remainder_scope), stmts.into_iter())); - unpack!(block = this.in_scope(init_scope, block, move |this| { - // FIXME #30046 ^~~~ - match initializer { - Some(initializer) => { - this.expr_into_pattern(block, remainder_scope, pattern, initializer) - } - None => { - this.declare_bindings(remainder_scope, &pattern); - block.unit() - } - } - })); - } - - StmtKind::Expr { scope, expr } => { - unpack!(block = this.in_scope(scope, block, |this| { - let expr = this.hir.mirror(expr); - let temp = this.temp(expr.ty.clone()); - unpack!(block = this.into(&temp, block, expr)); - unpack!(block = this.build_drop(block, temp)); - block.unit() - })); - } - } - } - block.unit() - } -} diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 49617ed5171b..66cb1f56b916 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -26,7 +26,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { extent: cx.tcx.region_maps.node_extent(self.id), span: self.span, stmts: stmts, - expr: self.expr.to_ref(), + expr: self.expr.to_ref() } } } @@ -41,13 +41,13 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>, while let Some((index, stmt)) = stmts.next() { match stmt.node { hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) => - result.push( - StmtRef::Mirror( - Box::new(Stmt { span: stmt.span, - kind: StmtKind::Expr { - scope: cx.tcx.region_maps.node_extent(id), - expr: expr.to_ref() } }))), - + result.push(StmtRef::Mirror(Box::new(Stmt { + span: stmt.span, + kind: StmtKind::Expr { + scope: cx.tcx.region_maps.node_extent(id), + expr: expr.to_ref() + } + }))), hir::StmtDecl(ref decl, id) => { match decl.node { hir::DeclItem(..) => { /* ignore for purposes of the MIR */ } @@ -59,10 +59,6 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>, let remainder_extent = cx.tcx.region_maps.lookup_code_extent(remainder_extent); - // pull in all following statements, since - // they are within the scope of this let: - let following_stmts = mirror_stmts(cx, block_id, stmts); - let pattern = cx.irrefutable_pat(&local.pat); result.push(StmtRef::Mirror(Box::new(Stmt { span: stmt.span, @@ -71,11 +67,8 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>, init_scope: cx.tcx.region_maps.node_extent(id), pattern: pattern, initializer: local.init.to_ref(), - stmts: following_stmts, }, }))); - - return result; } } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index e8edd4067e2f..707dd972003f 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -78,10 +78,7 @@ pub enum StmtKind<'tcx> { pattern: Pattern<'tcx>, /// let pat = ... - initializer: Option>, - - /// let pat = init; - stmts: Vec>, + initializer: Option> }, }