about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-03-09 12:36:07 -0500
committerNiko Matsakis <niko@alum.mit.edu>2016-03-23 16:37:48 -0400
commit323d7f4e98c2e6039efb8c9afda405c156d21299 (patch)
tree1ed8e41d22dbd10eb6f0ba897fac1658b13cda09
parent464c02e336f15c6fedb7235e93ec6f8f69411b57 (diff)
downloadrust-323d7f4e98c2e6039efb8c9afda405c156d21299.tar.gz
rust-323d7f4e98c2e6039efb8c9afda405c156d21299.zip
record a scope for each `VarDecl`
-rw-r--r--src/librustc/mir/repr.rs2
-rw-r--r--src/librustc_mir/build/block.rs12
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs2
-rw-r--r--src/librustc_mir/build/expr/as_operand.rs2
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs4
-rw-r--r--src/librustc_mir/build/expr/as_temp.rs2
-rw-r--r--src/librustc_mir/build/expr/into.rs2
-rw-r--r--src/librustc_mir/build/matches/mod.rs38
-rw-r--r--src/librustc_mir/build/mod.rs4
-rw-r--r--src/librustc_mir/build/scope.rs13
10 files changed, 45 insertions, 36 deletions
diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs
index 6723fc72a40..ebf78792d72 100644
--- a/src/librustc/mir/repr.rs
+++ b/src/librustc/mir/repr.rs
@@ -159,6 +159,8 @@ pub struct VarDecl<'tcx> {
     pub mutability: Mutability,
     pub name: Name,
     pub ty: Ty<'tcx>,
+    pub scope: ScopeId, // scope in which variable was declared
+    pub span: Span, // span where variable was declared
 }
 
 /// A "temp" is a temporary that we place on the stack. They are
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index ca23be7dc06..b4c3e93b280 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -20,7 +20,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                      ast_block: &'tcx hir::Block)
                      -> BlockAnd<()> {
         let Block { extent, span, stmts, expr } = self.hir.mirror(ast_block);
-        self.in_scope(extent, block, move |this| {
+        self.in_scope(extent, block, move |this, _| {
             // 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:
             //
@@ -42,7 +42,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                 let Stmt { span: _, kind } = this.hir.mirror(stmt);
                 match kind {
                     StmtKind::Expr { scope, expr } => {
-                        unpack!(block = this.in_scope(scope, block, |this| {
+                        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));
@@ -51,14 +51,14 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                         }));
                     }
                     StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => {
-                        this.push_scope(remainder_scope, block);
+                        let remainder_scope_id = this.push_scope(remainder_scope, block);
                         let_extent_stack.push(remainder_scope);
-                        unpack!(block = this.in_scope(init_scope, block, move |this| {
+                        unpack!(block = this.in_scope(init_scope, block, move |this, _| {
                             // FIXME #30046                              ^~~~
                             if let Some(init) = initializer {
-                                this.expr_into_pattern(block, remainder_scope, pattern, init)
+                                this.expr_into_pattern(block, remainder_scope_id, pattern, init)
                             } else {
-                                this.declare_bindings(remainder_scope, &pattern);
+                                this.declare_bindings(remainder_scope_id, &pattern);
                                 block.unit()
                             }
                         }));
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index b2c7507ed7b..be2b70b8699 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -37,7 +37,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         let expr_span = expr.span;
         match expr.kind {
             ExprKind::Scope { extent, value } => {
-                this.in_scope(extent, block, |this| this.as_lvalue(block, value))
+                this.in_scope(extent, block, |this, _| this.as_lvalue(block, value))
             }
             ExprKind::Field { lhs, name } => {
                 let lvalue = unpack!(block = this.as_lvalue(block, lhs));
diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs
index 7738ebca26b..661d01ce989 100644
--- a/src/librustc_mir/build/expr/as_operand.rs
+++ b/src/librustc_mir/build/expr/as_operand.rs
@@ -35,7 +35,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         let this = self;
 
         if let ExprKind::Scope { extent, value } = expr.kind {
-            return this.in_scope(extent, block, |this| this.as_operand(block, value));
+            return this.in_scope(extent, block, |this, _| this.as_operand(block, value));
         }
 
         let category = Category::of(&expr.kind).unwrap();
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 4c0e9b98d9a..a77a64ec3d8 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -37,7 +37,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
 
         match expr.kind {
             ExprKind::Scope { extent, value } => {
-                this.in_scope(extent, block, |this| this.as_rvalue(block, value))
+                this.in_scope(extent, block, |this, _| this.as_rvalue(block, value))
             }
             ExprKind::InlineAsm { asm, outputs, inputs } => {
                 let outputs = outputs.into_iter().map(|output| {
@@ -76,7 +76,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                 let result = this.temp(expr.ty);
                 // to start, malloc some memory of suitable type (thus far, uninitialized):
                 this.cfg.push_assign(block, expr_span, &result, Rvalue::Box(value.ty));
-                this.in_scope(value_extents, block, |this| {
+                this.in_scope(value_extents, block, |this, _| {
                     // schedule a shallow free of that memory, lest we unwind:
                     this.schedule_box_free(expr_span, value_extents, &result, value.ty);
                     // initialize the box contents:
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index 27c374e1ac2..2041fef885d 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -30,7 +30,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         let this = self;
 
         if let ExprKind::Scope { extent, value } = expr.kind {
-            return this.in_scope(extent, block, |this| this.as_temp(block, value));
+            return this.in_scope(extent, block, |this, _| this.as_temp(block, value));
         }
 
         let expr_ty = expr.ty.clone();
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index a7f4a53b022..ce2b7dc34eb 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -39,7 +39,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
 
         match expr.kind {
             ExprKind::Scope { extent, value } => {
-                this.in_scope(extent, block, |this| this.into(destination, block, value))
+                this.in_scope(extent, block, |this, _| this.into(destination, block, value))
             }
             ExprKind::Block { body: ast_block } => {
                 this.ast_block(destination, block, ast_block)
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 673ff9e86c4..bc92da30cab 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -16,7 +16,6 @@
 use build::{BlockAnd, BlockAndExtension, Builder};
 use rustc_data_structures::fnv::FnvHashMap;
 use rustc::middle::const_eval::ConstVal;
-use rustc::middle::region::CodeExtent;
 use rustc::middle::ty::{AdtDef, Ty};
 use rustc::mir::repr::*;
 use hair::*;
@@ -42,9 +41,9 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         // suitable extent for all of the bindings in this match. It's
         // easiest to do this up front because some of these arms may
         // be unreachable or reachable multiple times.
-        let var_extent = self.extent_of_innermost_scope();
+        let var_scope_id = self.innermost_scope_id();
         for arm in &arms {
-            self.declare_bindings(var_extent, &arm.patterns[0]);
+            self.declare_bindings(var_scope_id, &arm.patterns[0]);
         }
 
         let mut arm_blocks = ArmBlocks {
@@ -106,7 +105,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
 
     pub fn expr_into_pattern(&mut self,
                              mut block: BasicBlock,
-                             var_extent: CodeExtent, // lifetime of vars
+                             var_scope_id: ScopeId, // lifetime of vars
                              irrefutable_pat: Pattern<'tcx>,
                              initializer: ExprRef<'tcx>)
                              -> BlockAnd<()> {
@@ -118,7 +117,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                                    var,
                                    ty,
                                    subpattern: None } => {
-                let index = self.declare_binding(var_extent,
+                let index = self.declare_binding(var_scope_id,
                                                  mutability,
                                                  name,
                                                  var,
@@ -131,19 +130,19 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         }
         let lvalue = unpack!(block = self.as_lvalue(block, initializer));
         self.lvalue_into_pattern(block,
-                                 var_extent,
+                                 var_scope_id,
                                  irrefutable_pat,
                                  &lvalue)
     }
 
     pub fn lvalue_into_pattern(&mut self,
                                mut block: BasicBlock,
-                               var_extent: CodeExtent,
+                               var_scope_id: ScopeId,
                                irrefutable_pat: Pattern<'tcx>,
                                initializer: &Lvalue<'tcx>)
                                -> BlockAnd<()> {
         // first, creating the bindings
-        self.declare_bindings(var_extent, &irrefutable_pat);
+        self.declare_bindings(var_scope_id, &irrefutable_pat);
 
         // create a dummy candidate
         let mut candidate = Candidate {
@@ -170,29 +169,29 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         block.unit()
     }
 
-    pub fn declare_bindings(&mut self, var_extent: CodeExtent, pattern: &Pattern<'tcx>) {
+    pub fn declare_bindings(&mut self, var_scope_id: ScopeId, pattern: &Pattern<'tcx>) {
         match *pattern.kind {
             PatternKind::Binding { mutability, name, mode: _, var, ty, ref subpattern } => {
-                self.declare_binding(var_extent, mutability, name, var, ty, pattern.span);
+                self.declare_binding(var_scope_id, mutability, name, var, ty, pattern.span);
                 if let Some(subpattern) = subpattern.as_ref() {
-                    self.declare_bindings(var_extent, subpattern);
+                    self.declare_bindings(var_scope_id, subpattern);
                 }
             }
             PatternKind::Array { ref prefix, ref slice, ref suffix } |
             PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
                 for subpattern in prefix.iter().chain(slice).chain(suffix) {
-                    self.declare_bindings(var_extent, subpattern);
+                    self.declare_bindings(var_scope_id, subpattern);
                 }
             }
             PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {
             }
             PatternKind::Deref { ref subpattern } => {
-                self.declare_bindings(var_extent, subpattern);
+                self.declare_bindings(var_scope_id, subpattern);
             }
             PatternKind::Leaf { ref subpatterns } |
             PatternKind::Variant { ref subpatterns, .. } => {
                 for subpattern in subpatterns {
-                    self.declare_bindings(var_extent, &subpattern.pattern);
+                    self.declare_bindings(var_scope_id, &subpattern.pattern);
                 }
             }
         }
@@ -590,7 +589,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
     }
 
     fn declare_binding(&mut self,
-                       var_extent: CodeExtent,
+                       var_scope_id: ScopeId,
                        mutability: Mutability,
                        name: Name,
                        var_id: NodeId,
@@ -598,17 +597,20 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                        span: Span)
                        -> u32
     {
-        debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, var_extent={:?}, span={:?})",
-               var_id, name, var_ty, var_extent, span);
+        debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, var_scope_id={:?}, span={:?})",
+               var_id, name, var_ty, var_scope_id, span);
 
         let index = self.var_decls.len();
         self.var_decls.push(VarDecl::<'tcx> {
+            scope: var_scope_id,
             mutability: mutability,
             name: name,
             ty: var_ty.clone(),
+            span: span,
         });
         let index = index as u32;
-        self.schedule_drop(span, var_extent, &Lvalue::Var(index), var_ty);
+        let extent = self.scope_auxiliary[var_scope_id.index()].extent;
+        self.schedule_drop(span, extent, &Lvalue::Var(index), var_ty);
         self.var_indices.insert(var_id, index);
 
         debug!("declare_binding: index={:?}", index);
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 41259f8a281..4bb6b20a5d5 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -192,7 +192,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                      ast_block: &'tcx hir::Block)
                      -> BlockAnd<Vec<ArgDecl<'tcx>>>
     {
-        self.in_scope(argument_extent, block, |this| {
+        self.in_scope(argument_extent, block, |this, argument_scope_id| {
             // to start, translate the argument patterns and collect the argument types.
             let implicits = implicit_arguments.into_iter().map(|ty| (ty, None));
             let explicits = explicit_arguments.into_iter().map(|(ty, pat)| (ty, Some(pat)));
@@ -205,7 +205,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                     if let Some(pattern) = pattern {
                         let pattern = this.hir.irrefutable_pat(pattern);
                         unpack!(block = this.lvalue_into_pattern(block,
-                                                                 argument_extent,
+                                                                 argument_scope_id,
                                                                  pattern,
                                                                  &lvalue));
                     }
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 6a734e1816a..1dd9ec5bae5 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -208,11 +208,11 @@ impl<'a,'tcx> Builder<'a,'tcx> {
     /// Convenience wrapper that pushes a scope and then executes `f`
     /// to build its contents, popping the scope afterwards.
     pub fn in_scope<F, R>(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F) -> BlockAnd<R>
-        where F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<R>
+        where F: FnOnce(&mut Builder<'a, 'tcx>, ScopeId) -> BlockAnd<R>
     {
         debug!("in_scope(extent={:?}, block={:?})", extent, block);
-        self.push_scope(extent, block);
-        let rv = unpack!(block = f(self));
+        let id = self.push_scope(extent, block);
+        let rv = unpack!(block = f(self, id));
         unpack!(block = self.pop_scope(extent, block));
         debug!("in_scope: exiting extent={:?} block={:?}", extent, block);
         block.and(rv)
@@ -222,7 +222,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
     /// scope and call `pop_scope` afterwards. Note that these two
     /// calls must be paired; using `in_scope` as a convenience
     /// wrapper maybe preferable.
-    pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) {
+    pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) -> ScopeId {
         debug!("push_scope({:?})", extent);
         let parent_id = self.scopes.last().map(|s| s.id);
         let id = ScopeId::new(self.scope_data_vec.vec.len());
@@ -240,6 +240,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
             dom: self.cfg.current_location(entry),
             postdoms: vec![]
         });
+        id
     }
 
     /// Pops a scope, which should have extent `extent`, adding any
@@ -321,6 +322,10 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         }.unwrap_or_else(|| hir.span_bug(span, "no enclosing loop scope found?"))
     }
 
+    pub fn innermost_scope_id(&self) -> ScopeId {
+        self.scopes.last().map(|scope| scope.id).unwrap()
+    }
+
     pub fn extent_of_innermost_scope(&self) -> CodeExtent {
         self.scopes.last().map(|scope| scope.extent).unwrap()
     }