]> git.lizzy.rs Git - rust.git/commitdiff
mir: group span + visibility scope under a new SourceInfo type.
authorEduard Burtescu <edy.burt@gmail.com>
Tue, 7 Jun 2016 16:21:56 +0000 (19:21 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Tue, 7 Jun 2016 16:21:56 +0000 (19:21 +0300)
28 files changed:
src/librustc/mir/repr.rs
src/librustc/mir/visit.rs
src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_borrowck/borrowck/mir/patch.rs
src/librustc_mir/build/block.rs
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/expr/as_lvalue.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/expr/as_temp.rs
src/librustc_mir/build/expr/into.rs
src/librustc_mir/build/expr/stmt.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/matches/util.rs
src/librustc_mir/build/misc.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/pretty.rs
src/librustc_mir/transform/add_call_guards.rs
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/type_check.rs
src/librustc_trans/debuginfo/create_scope_map.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/statement.rs

index 0d9c46461619d3954a98ea46a1b579b3bbaf5a8c..e6c22d0ea3446076fe097d915197d34694068bac 100644 (file)
@@ -100,6 +100,18 @@ fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> {
     }
 }
 
+/// Grouped information about the source code origin of a MIR entity.
+/// Intended to be inspected by diagnostics and debuginfo.
+/// Most passes can work with it as a whole, within a single function.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+pub struct SourceInfo {
+    /// Source span for the AST pertaining to this MIR entity.
+    pub span: Span,
+
+    /// The lexical visibility scope, i.e. which bindings can be seen.
+    pub scope: VisibilityScope
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Mutability and borrow kinds
 
@@ -172,11 +184,8 @@ pub struct VarDecl<'tcx> {
     /// type inferred for this variable (`let x: ty = ...`)
     pub ty: Ty<'tcx>,
 
-    /// scope in which variable was declared
-    pub scope: VisibilityScope,
-
-    /// span where variable was declared
-    pub span: Span,
+    /// source information (span, scope, etc.) for the declaration
+    pub source_info: SourceInfo,
 }
 
 /// A "temp" is a temporary that we place on the stack. They are
@@ -275,8 +284,7 @@ pub struct BasicBlockData<'tcx> {
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct Terminator<'tcx> {
-    pub span: Span,
-    pub scope: VisibilityScope,
+    pub source_info: SourceInfo,
     pub kind: TerminatorKind<'tcx>
 }
 
@@ -587,8 +595,7 @@ pub enum AssertMessage<'tcx> {
 
 #[derive(Clone, RustcEncodable, RustcDecodable)]
 pub struct Statement<'tcx> {
-    pub span: Span,
-    pub scope: VisibilityScope,
+    pub source_info: SourceInfo,
     pub kind: StatementKind<'tcx>,
 }
 
index d340695761de083a179a4550306d34060492c6da..dbe48d6b09447735b02605c44ef9e4871184d060 100644 (file)
@@ -186,6 +186,11 @@ fn visit_span(&mut self,
                 self.super_span(span);
             }
 
+            fn visit_source_info(&mut self,
+                                 source_info: & $($mutability)* SourceInfo) {
+                self.super_source_info(source_info);
+            }
+
             fn visit_fn_output(&mut self,
                                fn_output: & $($mutability)* FnOutput<'tcx>) {
                 self.super_fn_output(fn_output);
@@ -319,13 +324,11 @@ fn super_statement(&mut self,
                                block: BasicBlock,
                                statement: & $($mutability)* Statement<'tcx>) {
                 let Statement {
-                    ref $($mutability)* span,
-                    ref $($mutability)* scope,
+                    ref $($mutability)* source_info,
                     ref $($mutability)* kind,
                 } = *statement;
 
-                self.visit_span(span);
-                self.visit_visibility_scope(scope);
+                self.visit_source_info(source_info);
                 match *kind {
                     StatementKind::Assign(ref $($mutability)* lvalue,
                                           ref $($mutability)* rvalue) => {
@@ -346,13 +349,11 @@ fn super_terminator(&mut self,
                                 block: BasicBlock,
                                 terminator: &$($mutability)* Terminator<'tcx>) {
                 let Terminator {
-                    ref $($mutability)* span,
-                    ref $($mutability)* scope,
+                    ref $($mutability)* source_info,
                     ref $($mutability)* kind,
                 } = *terminator;
 
-                self.visit_span(span);
-                self.visit_visibility_scope(scope);
+                self.visit_source_info(source_info);
                 self.visit_terminator_kind(block, kind);
             }
 
@@ -622,13 +623,11 @@ fn super_var_decl(&mut self,
                     mutability: _,
                     name: _,
                     ref $($mutability)* ty,
-                    ref $($mutability)* scope,
-                    ref $($mutability)* span,
+                    ref $($mutability)* source_info,
                 } = *var_decl;
 
                 self.visit_ty(ty);
-                self.visit_visibility_scope(scope);
-                self.visit_span(span);
+                self.visit_source_info(source_info);
             }
 
             fn super_temp_decl(&mut self,
@@ -707,6 +706,16 @@ fn super_def_id(&mut self, _def_id: & $($mutability)* DefId) {
             fn super_span(&mut self, _span: & $($mutability)* Span) {
             }
 
+            fn super_source_info(&mut self, source_info: & $($mutability)* SourceInfo) {
+                let SourceInfo {
+                    ref $($mutability)* span,
+                    ref $($mutability)* scope,
+                } = *source_info;
+
+                self.visit_span(span);
+                self.visit_visibility_scope(scope);
+            }
+
             fn super_fn_output(&mut self, fn_output: & $($mutability)* FnOutput<'tcx>) {
                 match *fn_output {
                     FnOutput::FnConverging(ref $($mutability)* ty) => {
index 74dc921b0bba55909c9901c3c098c3d5badf535f..8c528f10b57ba205e4e65a2661d69d971f232125 100644 (file)
@@ -151,7 +151,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            terminator: &'a Option<repr::Terminator<'tcx>>)
                            -> Option<(&'a [repr::Operand<'tcx>], Span)> {
-    if let Some(repr::Terminator { ref kind, span, .. }) = *terminator {
+    if let Some(repr::Terminator { ref kind, source_info, .. }) = *terminator {
         if let repr::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
         {
             if let repr::Operand::Constant(ref func) = *oper
@@ -161,7 +161,7 @@ fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     let name = tcx.item_name(def_id);
                     if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
                         if name.as_str() == "rustc_peek" {
-                            return Some((args, span));
+                            return Some((args, source_info.span));
                         }
                     }
                 }
index e783420fa065ce138f68361141b56e03386ce527..b09db70e7b88aa391a3aac8032bbe7aaa0e79b17 100644 (file)
@@ -124,8 +124,7 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
 
 #[derive(Copy, Clone, Debug)]
 struct DropCtxt<'a, 'tcx: 'a> {
-    span: Span,
-    scope: ScopeId,
+    source_info: SourceInfo,
     is_cleanup: bool,
 
     init_data: &'a InitializationData,
@@ -273,8 +272,7 @@ fn elaborate_drops(&mut self)
                     let init_data = self.initialization_data_at(loc);
                     let path = self.move_data().rev_lookup.find(location);
                     self.elaborate_drop(&DropCtxt {
-                        span: terminator.span,
-                        scope: terminator.scope,
+                        source_info: terminator.source_info,
                         is_cleanup: data.is_cleanup,
                         init_data: &init_data,
                         lvalue: location,
@@ -329,8 +327,7 @@ fn elaborate_replace(
 
         let assign = Statement {
             kind: StatementKind::Assign(location.clone(), Rvalue::Use(value.clone())),
-            span: terminator.span,
-            scope: terminator.scope
+            source_info: terminator.source_info
         };
 
         let unwind = unwind.unwrap_or(self.patch.resume_block());
@@ -367,8 +364,7 @@ fn elaborate_replace(
             let path = self.move_data().rev_lookup.find(location);
 
             self.elaborate_drop(&DropCtxt {
-                span: terminator.span,
-                scope: terminator.scope,
+                source_info: terminator.source_info,
                 is_cleanup: data.is_cleanup,
                 init_data: &init_data,
                 lvalue: location,
@@ -513,8 +509,7 @@ fn drop_halfladder<'a>(&mut self,
                     debug!("drop_ladder: for std field {} ({:?})", i, lv);
 
                     self.elaborated_drop_block(&DropCtxt {
-                        span: c.span,
-                        scope: c.scope,
+                        source_info: c.source_info,
                         is_cleanup: is_cleanup,
                         init_data: c.init_data,
                         lvalue: lv,
@@ -527,8 +522,7 @@ fn drop_halfladder<'a>(&mut self,
                     debug!("drop_ladder: for rest field {} ({:?})", i, lv);
 
                     let blk = self.complete_drop(&DropCtxt {
-                        span: c.span,
-                        scope: c.scope,
+                        source_info: c.source_info,
                         is_cleanup: is_cleanup,
                         init_data: c.init_data,
                         lvalue: lv,
@@ -785,7 +779,7 @@ fn new_block<'a>(&mut self,
         self.patch.new_block(BasicBlockData {
             statements: vec![],
             terminator: Some(Terminator {
-                scope: c.scope, span: c.span, kind: k
+                source_info: c.source_info, kind: k
             }),
             is_cleanup: is_cleanup
         })
@@ -858,11 +852,10 @@ fn unelaborated_free_block<'a>(
         let mut statements = vec![];
         if let Some(&flag) = self.drop_flags.get(&c.path) {
             statements.push(Statement {
-                span: c.span,
-                scope: c.scope,
+                source_info: c.source_info,
                 kind: StatementKind::Assign(
                     Lvalue::Temp(flag),
-                    self.constant_bool(c.span, false)
+                    self.constant_bool(c.source_info.span, false)
                 )
             });
         }
@@ -880,9 +873,9 @@ fn unelaborated_free_block<'a>(
         self.patch.new_block(BasicBlockData {
             statements: statements,
             terminator: Some(Terminator {
-                scope: c.scope, span: c.span, kind: TerminatorKind::Call {
+                source_info: c.source_info, kind: TerminatorKind::Call {
                     func: Operand::Constant(Constant {
-                        span: c.span,
+                        span: c.source_info.span,
                         ty: fty,
                         literal: Literal::Item {
                             def_id: free_func,
@@ -910,7 +903,7 @@ fn must_complete_drop<'a>(&self, c: &DropCtxt<'a, 'tcx>) -> bool {
             ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
                 if def.has_dtor() {
                     self.tcx.sess.span_warn(
-                        c.span,
+                        c.source_info.span,
                         &format!("dataflow bug??? moving out of type with dtor {:?}",
                                  c));
                     true
@@ -932,7 +925,7 @@ fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> {
 
     fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagState) {
         if let Some(&flag) = self.drop_flags.get(&path) {
-            let span = self.patch.context_for_location(self.mir, loc).0;
+            let span = self.patch.source_info_for_location(self.mir, loc).span;
             let val = self.constant_bool(span, val.value());
             self.patch.add_assign(loc, Lvalue::Temp(flag), val);
         }
@@ -940,7 +933,7 @@ fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagSta
 
     fn drop_flags_on_init(&mut self) {
         let loc = Location { block: START_BLOCK, index: 0 };
-        let span = self.patch.context_for_location(self.mir, loc).0;
+        let span = self.patch.source_info_for_location(self.mir, loc).span;
         let false_ = self.constant_bool(span, false);
         for flag in self.drop_flags.values() {
             self.patch.add_assign(loc, Lvalue::Temp(*flag), false_.clone());
index b390c19af1a5beadccbd90556e37f8d25281aa1b..b838881251da320fee3586c1e1e1a0d6f4e89c6f 100644 (file)
@@ -11,7 +11,6 @@
 use super::gather_moves::Location;
 use rustc::ty::Ty;
 use rustc::mir::repr::*;
-use syntax::codemap::Span;
 
 use std::iter;
 use std::u32;
@@ -62,8 +61,10 @@ pub fn new(mir: &Mir<'tcx>) -> Self {
             result.new_block(BasicBlockData {
                 statements: vec![],
                 terminator: Some(Terminator {
-                    span: mir.span,
-                    scope: ScopeId::new(0),
+                    source_info: SourceInfo {
+                        span: mir.span,
+                        scope: ARGUMENT_VISIBILITY_SCOPE
+                    },
                     kind: TerminatorKind::Resume
                 }),
                 is_cleanup: true
@@ -154,31 +155,30 @@ pub fn apply(self, mir: &mut Mir<'tcx>) {
             debug!("MirPatch: adding statement {:?} at loc {:?}+{}",
                    stmt, loc, delta);
             loc.index += delta;
-            let (span, scope) = Self::context_for_index(
+            let source_info = Self::source_info_for_index(
                 mir.basic_block_data(loc.block), loc
             );
             mir.basic_block_data_mut(loc.block).statements.insert(
                 loc.index, Statement {
-                    span: span,
-                    scope: scope,
+                    source_info: source_info,
                     kind: stmt
                 });
             delta += 1;
         }
     }
 
-    pub fn context_for_index(data: &BasicBlockData, loc: Location) -> (Span, ScopeId) {
+    pub fn source_info_for_index(data: &BasicBlockData, loc: Location) -> SourceInfo {
         match data.statements.get(loc.index) {
-            Some(stmt) => (stmt.span, stmt.scope),
-            None => (data.terminator().span, data.terminator().scope)
+            Some(stmt) => stmt.source_info,
+            None => data.terminator().source_info
         }
     }
 
-    pub fn context_for_location(&self, mir: &Mir, loc: Location) -> (Span, ScopeId) {
+    pub fn source_info_for_location(&self, mir: &Mir, loc: Location) -> SourceInfo {
         let data = match loc.block.index().checked_sub(mir.basic_blocks.len()) {
             Some(new) => &self.new_blocks[new],
             None => mir.basic_block_data(loc.block)
         };
-        Self::context_for_index(data, loc)
+        Self::source_info_for_index(data, loc)
     }
 }
index f4e4b78b64677d4647af1e492de514427de46902..7e650c5bd3d06c03f34c3f9494ff1e8ec4df2a8f 100644 (file)
@@ -83,8 +83,8 @@ pub fn ast_block(&mut self,
                 unpack!(block = this.into(destination, block, expr));
             } else if dest_is_unit {
                 // FIXME(#31472)
-                let scope_id = this.innermost_scope_id();
-                this.cfg.push_assign_unit(block, scope_id, span, destination);
+                let source_info = this.source_info(span);
+                this.cfg.push_assign_unit(block, source_info, destination);
             }
             // Finally, we pop all the let scopes before exiting out from the scope of block
             // itself.
index 4045497575d3cbee5453486dfc68f607c11327b9..95f87bf83261400414835ec98c9c6937ee1160c7 100644 (file)
@@ -15,7 +15,6 @@
 
 use build::{CFG, Location};
 use rustc::mir::repr::*;
-use syntax::codemap::Span;
 
 impl<'tcx> CFG<'tcx> {
     pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
@@ -50,47 +49,41 @@ pub fn current_location(&mut self, block: BasicBlock) -> Location {
 
     pub fn push_assign(&mut self,
                        block: BasicBlock,
-                       scope: VisibilityScope,
-                       span: Span,
+                       source_info: SourceInfo,
                        lvalue: &Lvalue<'tcx>,
                        rvalue: Rvalue<'tcx>) {
         self.push(block, Statement {
-            scope: scope,
-            span: span,
+            source_info: source_info,
             kind: StatementKind::Assign(lvalue.clone(), rvalue)
         });
     }
 
     pub fn push_assign_constant(&mut self,
                                 block: BasicBlock,
-                                scope: VisibilityScope,
-                                span: Span,
+                                source_info: SourceInfo,
                                 temp: &Lvalue<'tcx>,
                                 constant: Constant<'tcx>) {
-        self.push_assign(block, scope, span, temp,
+        self.push_assign(block, source_info, temp,
                          Rvalue::Use(Operand::Constant(constant)));
     }
 
     pub fn push_assign_unit(&mut self,
                             block: BasicBlock,
-                            scope: VisibilityScope,
-                            span: Span,
+                            source_info: SourceInfo,
                             lvalue: &Lvalue<'tcx>) {
-        self.push_assign(block, scope, span, lvalue, Rvalue::Aggregate(
+        self.push_assign(block, source_info, lvalue, Rvalue::Aggregate(
             AggregateKind::Tuple, vec![]
         ));
     }
 
     pub fn terminate(&mut self,
                      block: BasicBlock,
-                     scope: VisibilityScope,
-                     span: Span,
+                     source_info: SourceInfo,
                      kind: TerminatorKind<'tcx>) {
         debug_assert!(self.block_data(block).terminator.is_none(),
                       "terminate: block {:?} already has a terminator set", block);
         self.block_data_mut(block).terminator = Some(Terminator {
-            span: span,
-            scope: scope,
+            source_info: source_info,
             kind: kind,
         });
     }
index 1f78071dfcea4abdacf556a8b64b5702677daccc..8e33cfa9b0b52241e4f1db275f96aa3af855bc67 100644 (file)
@@ -34,8 +34,8 @@ fn expr_as_lvalue(&mut self,
         debug!("expr_as_lvalue(block={:?}, expr={:?})", block, expr);
 
         let this = self;
-        let scope_id = this.innermost_scope_id();
         let expr_span = expr.span;
+        let source_info = this.source_info(expr_span);
         match expr.kind {
             ExprKind::Scope { extent, value } => {
                 this.in_scope(extent, block, |this| this.as_lvalue(block, value))
@@ -59,9 +59,9 @@ fn expr_as_lvalue(&mut self,
 
                 // bounds check:
                 let (len, lt) = (this.temp(usize_ty.clone()), this.temp(bool_ty));
-                this.cfg.push_assign(block, scope_id, expr_span, // len = len(slice)
+                this.cfg.push_assign(block, source_info, // len = len(slice)
                                      &len, Rvalue::Len(slice.clone()));
-                this.cfg.push_assign(block, scope_id, expr_span, // lt = idx < len
+                this.cfg.push_assign(block, source_info, // lt = idx < len
                                      &lt, Rvalue::BinaryOp(BinOp::Lt,
                                                            idx.clone(),
                                                            Operand::Consume(len.clone())));
index 19a3bc4d0e91e2d5a427a034b485093bd0e27f2b..6524124c13b06a6abd771deba8e13d94376958a8 100644 (file)
@@ -41,8 +41,8 @@ fn expr_as_rvalue(&mut self,
         debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);
 
         let this = self;
-        let scope_id = this.innermost_scope_id();
         let expr_span = expr.span;
+        let source_info = this.source_info(expr_span);
 
         match expr.kind {
             ExprKind::Scope { extent, value } => {
@@ -86,7 +86,7 @@ fn expr_as_rvalue(&mut self,
                     let minval = this.minval_literal(expr_span, expr.ty);
                     let is_min = this.temp(bool_ty);
 
-                    this.cfg.push_assign(block, scope_id, expr_span, &is_min,
+                    this.cfg.push_assign(block, source_info, &is_min,
                                          Rvalue::BinaryOp(BinOp::Eq, arg.clone(), minval));
 
                     let err = ConstMathErr::Overflow(Op::Neg);
@@ -99,7 +99,7 @@ fn expr_as_rvalue(&mut self,
                 let value = this.hir.mirror(value);
                 let result = this.temp(expr.ty);
                 // to start, malloc some memory of suitable type (thus far, uninitialized):
-                this.cfg.push_assign(block, scope_id, expr_span, &result, Rvalue::Box(value.ty));
+                this.cfg.push_assign(block, source_info, &result, Rvalue::Box(value.ty));
                 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);
@@ -245,13 +245,13 @@ fn expr_as_rvalue(&mut self,
     pub fn build_binary_op(&mut self, mut block: BasicBlock,
                            op: BinOp, span: Span, ty: ty::Ty<'tcx>,
                            lhs: Operand<'tcx>, rhs: Operand<'tcx>) -> BlockAnd<Rvalue<'tcx>> {
-        let scope_id = self.innermost_scope_id();
+        let source_info = self.source_info(span);
         let bool_ty = self.hir.bool_ty();
         if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
             let result_tup = self.hir.tcx().mk_tup(vec![ty, bool_ty]);
             let result_value = self.temp(result_tup);
 
-            self.cfg.push_assign(block, scope_id, span,
+            self.cfg.push_assign(block, source_info,
                                  &result_value, Rvalue::CheckedBinaryOp(op,
                                                                         lhs,
                                                                         rhs));
@@ -292,7 +292,7 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
                 // Check for / 0
                 let is_zero = self.temp(bool_ty);
                 let zero = self.zero_literal(span, ty);
-                self.cfg.push_assign(block, scope_id, span, &is_zero,
+                self.cfg.push_assign(block, source_info, &is_zero,
                                      Rvalue::BinaryOp(BinOp::Eq, rhs.clone(), zero));
 
                 block = self.assert(block, Operand::Consume(is_zero), false,
@@ -310,14 +310,14 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
 
                     // this does (rhs == -1) & (lhs == MIN). It could short-circuit instead
 
-                    self.cfg.push_assign(block, scope_id, span, &is_neg_1,
+                    self.cfg.push_assign(block, source_info, &is_neg_1,
                                          Rvalue::BinaryOp(BinOp::Eq, rhs.clone(), neg_1));
-                    self.cfg.push_assign(block, scope_id, span, &is_min,
+                    self.cfg.push_assign(block, source_info, &is_min,
                                          Rvalue::BinaryOp(BinOp::Eq, lhs.clone(), min));
 
                     let is_neg_1 = Operand::Consume(is_neg_1);
                     let is_min = Operand::Consume(is_min);
-                    self.cfg.push_assign(block, scope_id, span, &of,
+                    self.cfg.push_assign(block, source_info, &of,
                                          Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min));
 
                     block = self.assert(block, Operand::Consume(of), false,
index 2a28f33180198a631c863b3700a10f8465afbd1c..da128b8dd56266ada2214ddb9c5241505d11643d 100644 (file)
@@ -49,8 +49,8 @@ fn expr_as_temp(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<
             Category::Lvalue => {
                 let lvalue = unpack!(block = this.as_lvalue(block, expr));
                 let rvalue = Rvalue::Use(Operand::Consume(lvalue));
-                let scope_id = this.innermost_scope_id();
-                this.cfg.push_assign(block, scope_id, expr_span, &temp, rvalue);
+                let source_info = this.source_info(expr_span);
+                this.cfg.push_assign(block, source_info, &temp, rvalue);
             }
             _ => {
                 unpack!(block = this.into(&temp, block, expr));
index fb77fc50f8686130221c4e56776b5de4c467c380..fd9ddc05ab5c4cfb3533fc42aadc4b2fce37d07d 100644 (file)
@@ -33,7 +33,7 @@ pub fn into_expr(&mut self,
         // just use the name `this` uniformly
         let this = self;
         let expr_span = expr.span;
-        let scope_id = this.innermost_scope_id();
+        let source_info = this.source_info(expr_span);
 
         match expr.kind {
             ExprKind::Scope { extent, value } => {
@@ -50,7 +50,7 @@ pub fn into_expr(&mut self,
 
                 let mut then_block = this.cfg.start_new_block();
                 let mut else_block = this.cfg.start_new_block();
-                this.cfg.terminate(block, scope_id, expr_span, TerminatorKind::If {
+                this.cfg.terminate(block, source_info, TerminatorKind::If {
                     cond: operand,
                     targets: (then_block, else_block)
                 });
@@ -61,19 +61,14 @@ pub fn into_expr(&mut self,
                 } else {
                     // Body of the `if` expression without an `else` clause must return `()`, thus
                     // we implicitly generate a `else {}` if it is not specified.
-                    let scope_id = this.innermost_scope_id();
-                    this.cfg.push_assign_unit(else_block, scope_id, expr_span, destination);
+                    this.cfg.push_assign_unit(else_block, source_info, destination);
                     else_block
                 };
 
                 let join_block = this.cfg.start_new_block();
-                this.cfg.terminate(then_block,
-                                   scope_id,
-                                   expr_span,
+                this.cfg.terminate(then_block, source_info,
                                    TerminatorKind::Goto { target: join_block });
-                this.cfg.terminate(else_block,
-                                   scope_id,
-                                   expr_span,
+                this.cfg.terminate(else_block, source_info,
                                    TerminatorKind::Goto { target: join_block });
 
                 join_block.unit()
@@ -100,19 +95,17 @@ pub fn into_expr(&mut self,
                     LogicalOp::And => (else_block, false_block),
                     LogicalOp::Or => (true_block, else_block),
                 };
-                this.cfg.terminate(block,
-                                   scope_id,
-                                   expr_span,
+                this.cfg.terminate(block, source_info,
                                    TerminatorKind::If { cond: lhs, targets: blocks });
 
                 let rhs = unpack!(else_block = this.as_operand(else_block, rhs));
-                this.cfg.terminate(else_block, scope_id, expr_span, TerminatorKind::If {
+                this.cfg.terminate(else_block, source_info, TerminatorKind::If {
                     cond: rhs,
                     targets: (true_block, false_block)
                 });
 
                 this.cfg.push_assign_constant(
-                    true_block, scope_id, expr_span, destination,
+                    true_block, source_info, destination,
                     Constant {
                         span: expr_span,
                         ty: this.hir.bool_ty(),
@@ -120,20 +113,16 @@ pub fn into_expr(&mut self,
                     });
 
                 this.cfg.push_assign_constant(
-                    false_block, scope_id, expr_span, destination,
+                    false_block, source_info, destination,
                     Constant {
                         span: expr_span,
                         ty: this.hir.bool_ty(),
                         literal: this.hir.false_literal(),
                     });
 
-                this.cfg.terminate(true_block,
-                                   scope_id,
-                                   expr_span,
+                this.cfg.terminate(true_block, source_info,
                                    TerminatorKind::Goto { target: join_block });
-                this.cfg.terminate(false_block,
-                                   scope_id,
-                                   expr_span,
+                this.cfg.terminate(false_block, source_info,
                                    TerminatorKind::Goto { target: join_block });
 
                 join_block.unit()
@@ -158,9 +147,7 @@ pub fn into_expr(&mut self,
                 let exit_block = this.cfg.start_new_block();
 
                 // start the loop
-                this.cfg.terminate(block,
-                                   scope_id,
-                                   expr_span,
+                this.cfg.terminate(block, source_info,
                                    TerminatorKind::Goto { target: loop_block });
 
                 let might_break = this.in_loop_scope(loop_block, exit_block, move |this| {
@@ -173,9 +160,7 @@ pub fn into_expr(&mut self,
                         let loop_block_end;
                         let cond = unpack!(loop_block_end = this.as_operand(loop_block, cond_expr));
                         body_block = this.cfg.start_new_block();
-                        this.cfg.terminate(loop_block_end,
-                                           scope_id,
-                                           expr_span,
+                        this.cfg.terminate(loop_block_end, source_info,
                                            TerminatorKind::If {
                                                cond: cond,
                                                targets: (body_block, exit_block)
@@ -192,15 +177,13 @@ pub fn into_expr(&mut self,
                     let tmp = this.get_unit_temp();
                     // Execute the body, branching back to the test.
                     let body_block_end = unpack!(this.into(&tmp, body_block, body));
-                    this.cfg.terminate(body_block_end,
-                                       scope_id,
-                                       expr_span,
+                    this.cfg.terminate(body_block_end, source_info,
                                        TerminatorKind::Goto { target: loop_block });
                 });
                 // If the loop may reach its exit_block, we assign an empty tuple to the
                 // destination to keep the MIR well-formed.
                 if might_break {
-                    this.cfg.push_assign_unit(exit_block, scope_id, expr_span, destination);
+                    this.cfg.push_assign_unit(exit_block, source_info, destination);
                 }
                 exit_block.unit()
             }
@@ -219,7 +202,7 @@ pub fn into_expr(&mut self,
 
                 let success = this.cfg.start_new_block();
                 let cleanup = this.diverge_cleanup();
-                this.cfg.terminate(block, scope_id, expr_span, TerminatorKind::Call {
+                this.cfg.terminate(block, source_info, TerminatorKind::Call {
                     func: fun,
                     args: args,
                     cleanup: cleanup,
@@ -269,7 +252,7 @@ pub fn into_expr(&mut self,
                 });
 
                 let rvalue = unpack!(block = this.as_rvalue(block, expr));
-                this.cfg.push_assign(block, scope_id, expr_span, destination, rvalue);
+                this.cfg.push_assign(block, source_info, destination, rvalue);
                 block.unit()
             }
         }
index add268d394ab73938dee6c54142ca47317c44745..ad55a3d8b73f268572cf19dd3cd3e877ad243493 100644 (file)
@@ -20,7 +20,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()> {
         let this = self;
         let expr_span = expr.span;
-        let scope_id = this.innermost_scope_id();
+        let source_info = this.source_info(expr.span);
         // Handle a number of expressions that don't need a destination at all. This
         // avoids needing a mountain of temporary `()` variables.
         match expr.kind {
@@ -31,7 +31,6 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
             ExprKind::Assign { lhs, rhs } => {
                 let lhs = this.hir.mirror(lhs);
                 let rhs = this.hir.mirror(rhs);
-                let scope_id = this.innermost_scope_id();
                 let lhs_span = lhs.span;
 
                 // Note: we evaluate assignments right-to-left. This
@@ -50,7 +49,7 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
                 } else {
                     let rhs = unpack!(block = this.as_rvalue(block, rhs));
                     let lhs = unpack!(block = this.as_lvalue(block, lhs));
-                    this.cfg.push_assign(block, scope_id, expr_span, &lhs, rhs);
+                    this.cfg.push_assign(block, source_info, &lhs, rhs);
                     block.unit()
                 }
             }
@@ -75,7 +74,7 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
                 // (overloaded ops should be desugared into a call).
                 let result = unpack!(block = this.build_binary_op(block, op, expr_span, lhs_ty,
                                                   Operand::Consume(lhs.clone()), rhs));
-                this.cfg.push_assign(block, scope_id, expr_span, &lhs, result);
+                this.cfg.push_assign(block, source_info, &lhs, result);
 
                 block.unit()
             }
@@ -93,8 +92,7 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
                 block = match value {
                     Some(value) => unpack!(this.into(&Lvalue::ReturnPointer, block, value)),
                     None => {
-                        this.cfg.push_assign_unit(block, scope_id,
-                                                  expr_span, &Lvalue::ReturnPointer);
+                        this.cfg.push_assign_unit(block, source_info, &Lvalue::ReturnPointer);
                         block
                     }
                 };
@@ -104,7 +102,6 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
                 this.cfg.start_new_block().unit()
             }
             _ => {
-                let expr_span = expr.span;
                 let expr_ty = expr.ty;
                 let temp = this.temp(expr.ty.clone());
                 unpack!(block = this.into(&temp, block, expr));
index 46c907009a379abc87ff781a94ed805c4fc8c070..6104679d6500f376f010f4503d6712d6e1f1745b 100644 (file)
@@ -89,18 +89,16 @@ pub fn match_expr(&mut self,
         // all the arm blocks will rejoin here
         let end_block = self.cfg.start_new_block();
 
-        let outer_visibility_scope = self.innermost_scope_id();
+        let outer_source_info = self.source_info(span);
         for (arm_index, (body, visibility_scope)) in arm_bodies.into_iter().enumerate() {
             let mut arm_block = arm_blocks.blocks[arm_index];
             // Re-enter the visibility scope we created the bindings in.
             self.visibility_scope = visibility_scope;
             unpack!(arm_block = self.into(destination, arm_block, body));
-            self.cfg.terminate(arm_block,
-                               outer_visibility_scope,
-                               span,
+            self.cfg.terminate(arm_block, outer_source_info,
                                TerminatorKind::Goto { target: end_block });
         }
-        self.visibility_scope = outer_visibility_scope;
+        self.visibility_scope = outer_source_info.scope;
 
         end_block.unit()
     }
@@ -170,7 +168,11 @@ pub fn declare_bindings(&mut self,
                 if var_scope.is_none() {
                     var_scope = Some(self.new_visibility_scope(scope_span));
                 }
-                self.declare_binding(var_scope.unwrap(), mutability, name, var, ty, pattern.span);
+                let source_info = SourceInfo {
+                    span: pattern.span,
+                    scope: var_scope.unwrap()
+                };
+                self.declare_binding(source_info, mutability, name, var, ty);
                 if let Some(subpattern) = subpattern.as_ref() {
                     var_scope = self.declare_bindings(var_scope, scope_span, subpattern);
                 }
@@ -382,17 +384,15 @@ fn join_otherwise_blocks(&mut self,
                              mut otherwise: Vec<BasicBlock>)
                              -> BasicBlock
     {
+        let source_info = self.source_info(span);
         otherwise.sort();
         otherwise.dedup(); // variant switches can introduce duplicate target blocks
-        let scope_id = self.innermost_scope_id();
         if otherwise.len() == 1 {
             otherwise[0]
         } else {
             let join_block = self.cfg.start_new_block();
             for block in otherwise {
-                self.cfg.terminate(block,
-                                   scope_id,
-                                   span,
+                self.cfg.terminate(block, source_info,
                                    TerminatorKind::Goto { target: join_block });
             }
             join_block
@@ -571,24 +571,20 @@ fn bind_and_guard_matched_candidate<'pat>(&mut self,
 
         let arm_block = arm_blocks.blocks[candidate.arm_index];
 
-        let scope_id = self.innermost_scope_id();
         if let Some(guard) = candidate.guard {
             // the block to branch to if the guard fails; if there is no
             // guard, this block is simply unreachable
             let guard = self.hir.mirror(guard);
-            let guard_span = guard.span;
+            let source_info = self.source_info(guard.span);
             let cond = unpack!(block = self.as_operand(block, guard));
             let otherwise = self.cfg.start_new_block();
-            self.cfg.terminate(block,
-                               scope_id,
-                               guard_span,
+            self.cfg.terminate(block, source_info,
                                TerminatorKind::If { cond: cond,
                                                     targets: (arm_block, otherwise)});
             Some(otherwise)
         } else {
-            self.cfg.terminate(block,
-                               scope_id,
-                               candidate.span,
+            let source_info = self.source_info(candidate.span);
+            self.cfg.terminate(block, source_info,
                                TerminatorKind::Goto { target: arm_block });
             None
         }
@@ -614,35 +610,33 @@ fn bind_matched_candidate(&mut self,
                     Rvalue::Ref(region, borrow_kind, binding.source),
             };
 
-            let scope_id = self.innermost_scope_id();
-            self.cfg.push_assign(block, scope_id, binding.span,
+            let source_info = self.source_info(binding.span);
+            self.cfg.push_assign(block, source_info,
                                  &Lvalue::Var(var_index), rvalue);
         }
     }
 
     fn declare_binding(&mut self,
-                       var_scope_id: VisibilityScope,
+                       source_info: SourceInfo,
                        mutability: Mutability,
                        name: Name,
                        var_id: NodeId,
-                       var_ty: Ty<'tcx>,
-                       span: Span)
+                       var_ty: Ty<'tcx>)
                        -> u32
     {
-        debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, var_scope_id={:?}, span={:?})",
-               var_id, name, var_ty, var_scope_id, span);
+        debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, source_info={:?})",
+               var_id, name, var_ty, source_info);
 
         let index = self.var_decls.len();
         self.var_decls.push(VarDecl::<'tcx> {
-            scope: var_scope_id,
+            source_info: source_info,
             mutability: mutability,
             name: name,
             ty: var_ty.clone(),
-            span: span,
         });
         let index = index as u32;
         let extent = self.extent_of_innermost_scope();
-        self.schedule_drop(span, extent, &Lvalue::Var(index), var_ty);
+        self.schedule_drop(source_info.span, extent, &Lvalue::Var(index), var_ty);
         self.var_indices.insert(var_id, index);
 
         debug!("declare_binding: index={:?}", index);
index 09c146537e7d4f9d02d3d27d999b9b8bbd2bab8c..1f0c4bd9e0dd6e911ead8a22302a6f2bf46d893b 100644 (file)
@@ -176,7 +176,7 @@ pub fn perform_test(&mut self,
                         lvalue: &Lvalue<'tcx>,
                         test: &Test<'tcx>)
                         -> Vec<BasicBlock> {
-        let scope_id = self.innermost_scope_id();
+        let source_info = self.source_info(test.span);
         match test.kind {
             TestKind::Switch { adt_def, ref variants } => {
                 let num_enum_variants = self.hir.num_variants(adt_def);
@@ -193,7 +193,7 @@ pub fn perform_test(&mut self,
                 }).collect();
                 debug!("num_enum_variants: {}, num tested variants: {}, variants: {:?}",
                        num_enum_variants, variants.iter().count(), variants);
-                self.cfg.terminate(block, scope_id, test.span, TerminatorKind::Switch {
+                self.cfg.terminate(block, source_info, TerminatorKind::Switch {
                     discr: lvalue.clone(),
                     adt_def: adt_def,
                     targets: target_blocks.clone()
@@ -245,10 +245,7 @@ pub fn perform_test(&mut self,
                     }
                 };
 
-                self.cfg.terminate(block,
-                                   scope_id,
-                                   test.span,
-                                   term);
+                self.cfg.terminate(block, source_info, term);
                 targets
             }
 
@@ -265,7 +262,7 @@ pub fn perform_test(&mut self,
                         if let ty::TyArray(_, _) = mt.ty.sty {
                             ty = tcx.mk_imm_ref(region, tcx.mk_slice(tcx.types.u8));
                             let val_slice = self.temp(ty);
-                            self.cfg.push_assign(block, scope_id, test.span, &val_slice,
+                            self.cfg.push_assign(block, source_info, &val_slice,
                                                  Rvalue::Cast(CastKind::Unsize, val, ty));
                             val = Operand::Consume(val_slice);
                         }
@@ -280,7 +277,7 @@ pub fn perform_test(&mut self,
                     });
 
                     let slice = self.temp(ty);
-                    self.cfg.push_assign(block, scope_id, test.span, &slice,
+                    self.cfg.push_assign(block, source_info, &slice,
                                          Rvalue::Cast(CastKind::Unsize, array, ty));
                     Operand::Consume(slice)
                 } else {
@@ -301,7 +298,7 @@ pub fn perform_test(&mut self,
                     let eq_result = self.temp(bool_ty);
                     let eq_block = self.cfg.start_new_block();
                     let cleanup = self.diverge_cleanup();
-                    self.cfg.terminate(block, scope_id, test.span, TerminatorKind::Call {
+                    self.cfg.terminate(block, source_info, TerminatorKind::Call {
                         func: Operand::Constant(Constant {
                             span: test.span,
                             ty: mty,
@@ -314,7 +311,7 @@ pub fn perform_test(&mut self,
 
                     // check the result
                     let block = self.cfg.start_new_block();
-                    self.cfg.terminate(eq_block, scope_id, test.span, TerminatorKind::If {
+                    self.cfg.terminate(eq_block, source_info, TerminatorKind::If {
                         cond: Operand::Consume(eq_result),
                         targets: (block, fail),
                     });
@@ -344,17 +341,14 @@ pub fn perform_test(&mut self,
                 let (actual, result) = (self.temp(usize_ty), self.temp(bool_ty));
 
                 // actual = len(lvalue)
-                self.cfg.push_assign(block, scope_id, test.span,
+                self.cfg.push_assign(block, source_info,
                                      &actual, Rvalue::Len(lvalue.clone()));
 
                 // expected = <N>
-                let expected = self.push_usize(block, scope_id, test.span, len);
+                let expected = self.push_usize(block, source_info, len);
 
                 // result = actual == expected OR result = actual < expected
-                self.cfg.push_assign(block,
-                                     scope_id,
-                                     test.span,
-                                     &result,
+                self.cfg.push_assign(block, source_info, &result,
                                      Rvalue::BinaryOp(op,
                                                       Operand::Consume(actual),
                                                       Operand::Consume(expected)));
@@ -362,7 +356,7 @@ pub fn perform_test(&mut self,
                 // branch based on result
                 let target_blocks: Vec<_> = vec![self.cfg.start_new_block(),
                                                  self.cfg.start_new_block()];
-                self.cfg.terminate(block, scope_id, test.span, TerminatorKind::If {
+                self.cfg.terminate(block, source_info, TerminatorKind::If {
                     cond: Operand::Consume(result),
                     targets: (target_blocks[0], target_blocks[1])
                 });
@@ -383,13 +377,13 @@ fn compare(&mut self,
         let result = self.temp(bool_ty);
 
         // result = op(left, right)
-        let scope_id = self.innermost_scope_id();
-        self.cfg.push_assign(block, scope_id, span, &result,
+        let source_info = self.source_info(span);
+        self.cfg.push_assign(block, source_info, &result,
                              Rvalue::BinaryOp(op, left, right));
 
         // branch based on result
         let target_block = self.cfg.start_new_block();
-        self.cfg.terminate(block, scope_id, span, TerminatorKind::If {
+        self.cfg.terminate(block, source_info, TerminatorKind::If {
             cond: Operand::Consume(result),
             targets: (target_block, fail_block)
         });
index 5eb58f7612d744c5b9e38943bd5d1020190751a2..2e9cc96c046817d2a4f4fbd6330f3cc243c21926 100644 (file)
@@ -65,8 +65,8 @@ pub fn prefix_suffix_slice<'pat>(&mut self,
                 from_end: suffix_len,
             };
             let temp = self.temp(slice.ty.clone()); // no need to schedule drop, temp is always copy
-            let scope_id = self.innermost_scope_id();
-            self.cfg.push_assign(block, scope_id, slice.span, &temp, rvalue);
+            let source_info = self.source_info(slice.span);
+            self.cfg.push_assign(block, source_info, &temp, rvalue);
             match_pairs.push(MatchPair::new(temp, slice));
         }
 
index a6294406ea5671d90e26cbdc5b74eda88ee77b62..a9d5c0c4f85c39314b86d0ff985b589b745f42a1 100644 (file)
@@ -103,16 +103,15 @@ pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
 
     pub fn push_usize(&mut self,
                       block: BasicBlock,
-                      scope_id: VisibilityScope,
-                      span: Span,
+                      source_info: SourceInfo,
                       value: u64)
                       -> Lvalue<'tcx> {
         let usize_ty = self.hir.usize_ty();
         let temp = self.temp(usize_ty);
         self.cfg.push_assign_constant(
-            block, scope_id, span, &temp,
+            block, source_info, &temp,
             Constant {
-                span: span,
+                span: source_info.span,
                 ty: self.hir.usize_ty(),
                 literal: self.hir.usize_literal(value),
             });
index 27cced2ae1ac786d81fd4fe48f2bb416b8e4162a..9c1b9fa4437e01110826ea8e525f42c509f9b673 100644 (file)
@@ -200,11 +200,11 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
             builder.args_and_body(block, return_ty, arguments, arg_extent, ast_block)
         }));
 
-        let visibility_scope = builder.visibility_scope;
+        let source_info = builder.source_info(span);
         let return_block = builder.return_block();
-        builder.cfg.terminate(block, visibility_scope, span,
+        builder.cfg.terminate(block, source_info,
                               TerminatorKind::Goto { target: return_block });
-        builder.cfg.terminate(return_block, visibility_scope, span,
+        builder.cfg.terminate(return_block, source_info,
                               TerminatorKind::Return);
         return_block.and(arg_decls)
     }));
@@ -260,11 +260,11 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
         let expr = builder.hir.mirror(ast_expr);
         unpack!(block = builder.into(&Lvalue::ReturnPointer, block, expr));
 
-        let visibility_scope = builder.visibility_scope;
+        let source_info = builder.source_info(span);
         let return_block = builder.return_block();
-        builder.cfg.terminate(block, visibility_scope, span,
+        builder.cfg.terminate(block, source_info,
                               TerminatorKind::Goto { target: return_block });
-        builder.cfg.terminate(return_block, visibility_scope, span,
+        builder.cfg.terminate(return_block, source_info,
                               TerminatorKind::Return);
 
         return_block.unit()
index 93ca01ba2ec4ae3cd23714d11069bb9f09112c38..2b7efa52cbd054c8131dfaed4e997e751aa8642f 100644 (file)
@@ -207,6 +207,14 @@ fn cached_block(&self) -> Option<BasicBlock> {
             None
         }
     }
+
+    /// Given a span and this scope's visibility scope, make a SourceInfo.
+    fn source_info(&self, span: Span) -> SourceInfo {
+        SourceInfo {
+            span: span,
+            scope: self.visibility_scope
+        }
+    }
 }
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
@@ -318,7 +326,7 @@ pub fn exit_scope(&mut self,
             if let Some(ref free_data) = scope.free {
                 let next = self.cfg.start_new_block();
                 let free = build_free(self.hir.tcx(), &tmp, free_data, next);
-                self.cfg.terminate(block, scope.visibility_scope, span, free);
+                self.cfg.terminate(block, scope.source_info(span), free);
                 block = next;
             }
             self.scope_auxiliary[scope.id]
@@ -332,8 +340,7 @@ pub fn exit_scope(&mut self,
                                             .next()
                                             .unwrap();
         self.cfg.terminate(block,
-                           scope.visibility_scope,
-                           span,
+                           scope.source_info(span),
                            TerminatorKind::Goto { target: target });
     }
 
@@ -372,8 +379,12 @@ pub fn find_loop_scope(&mut self,
         }.unwrap_or_else(|| span_bug!(span, "no enclosing loop scope found?"))
     }
 
-    pub fn innermost_scope_id(&self) -> VisibilityScope {
-        self.visibility_scope
+    /// Given a span and the current visibility scope, make a SourceInfo.
+    pub fn source_info(&self, span: Span) -> SourceInfo {
+        SourceInfo {
+            span: span,
+            scope: self.visibility_scope
+        }
     }
 
     pub fn extent_of_innermost_scope(&self) -> CodeExtent {
@@ -491,8 +502,7 @@ pub fn diverge_cleanup(&mut self) -> Option<BasicBlock> {
         } else {
             let resumeblk = cfg.start_new_cleanup_block();
             cfg.terminate(resumeblk,
-                          scopes[0].visibility_scope,
-                          self.fn_span,
+                          scopes[0].source_info(self.fn_span),
                           TerminatorKind::Resume);
             *cached_resume_block = Some(resumeblk);
             resumeblk
@@ -514,12 +524,10 @@ pub fn build_drop(&mut self,
         if !self.hir.needs_drop(ty) {
             return block.unit();
         }
-        let scope_id = self.innermost_scope_id();
+        let source_info = self.source_info(span);
         let next_target = self.cfg.start_new_block();
         let diverge_target = self.diverge_cleanup();
-        self.cfg.terminate(block,
-                           scope_id,
-                           span,
+        self.cfg.terminate(block, source_info,
                            TerminatorKind::Drop {
                                location: location,
                                target: next_target,
@@ -534,12 +542,10 @@ pub fn build_drop_and_replace(&mut self,
                                   span: Span,
                                   location: Lvalue<'tcx>,
                                   value: Operand<'tcx>) -> BlockAnd<()> {
-        let scope_id = self.innermost_scope_id();
+        let source_info = self.source_info(span);
         let next_target = self.cfg.start_new_block();
         let diverge_target = self.diverge_cleanup();
-        self.cfg.terminate(block,
-                           scope_id,
-                           span,
+        self.cfg.terminate(block, source_info,
                            TerminatorKind::DropAndReplace {
                                location: location,
                                value: value,
@@ -574,18 +580,18 @@ pub fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span) {
         let elems = vec![Operand::Constant(message),
                          Operand::Constant(file),
                          Operand::Constant(line)];
-        let scope_id = self.innermost_scope_id();
+        let source_info = self.source_info(span);
         // FIXME: We should have this as a constant, rather than a stack variable (to not pollute
         // icache with cold branch code), however to achieve that we either have to rely on rvalue
         // promotion or have some way, in MIR, to create constants.
-        self.cfg.push_assign(block, scope_id, span, &tuple, // [1]
+        self.cfg.push_assign(block, source_info, &tuple, // [1]
                              Rvalue::Aggregate(AggregateKind::Tuple, elems));
         // [1] tuple = (message_arg, file_arg, line_arg);
         // FIXME: is this region really correct here?
-        self.cfg.push_assign(block, scope_id, span, &tuple_ref, // tuple_ref = &tuple;
+        self.cfg.push_assign(block, source_info, &tuple_ref, // tuple_ref = &tuple;
                              Rvalue::Ref(region, BorrowKind::Shared, tuple));
         let cleanup = self.diverge_cleanup();
-        self.cfg.terminate(block, scope_id, span, TerminatorKind::Call {
+        self.cfg.terminate(block, source_info, TerminatorKind::Call {
             func: Operand::Constant(func),
             args: vec![Operand::Consume(tuple_ref)],
             cleanup: cleanup,
@@ -602,12 +608,12 @@ pub fn assert(&mut self, block: BasicBlock,
                   msg: AssertMessage<'tcx>,
                   span: Span)
                   -> BasicBlock {
-        let scope_id = self.innermost_scope_id();
+        let source_info = self.source_info(span);
 
         let success_block = self.cfg.start_new_block();
         let cleanup = self.diverge_cleanup();
 
-        self.cfg.terminate(block, scope_id, span,
+        self.cfg.terminate(block, source_info,
                            TerminatorKind::Assert {
                                cond: cond,
                                expected: expected,
@@ -670,7 +676,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
             earlier_scopes.iter().rev().flat_map(|s| s.cached_block()).next()
         });
         let next = cfg.start_new_block();
-        cfg.terminate(block, scope.visibility_scope, drop_data.span, TerminatorKind::Drop {
+        cfg.terminate(block, scope.source_info(drop_data.span), TerminatorKind::Drop {
             location: drop_data.location.clone(),
             target: next,
             unwind: on_diverge
@@ -700,15 +706,19 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
     // remainder. If everything is cached, we'll just walk right to
     // left reading the cached results but never created anything.
 
+    let visibility_scope = scope.visibility_scope;
+    let source_info = |span| SourceInfo {
+        span: span,
+        scope: visibility_scope
+    };
+
     // Next, build up any free.
     if let Some(ref mut free_data) = scope.free {
         target = if let Some(cached_block) = free_data.cached_block {
             cached_block
         } else {
             let into = cfg.start_new_cleanup_block();
-            cfg.terminate(into,
-                          scope.visibility_scope,
-                          free_data.span,
+            cfg.terminate(into, source_info(free_data.span),
                           build_free(tcx, unit_temp, free_data, target));
             free_data.cached_block = Some(into);
             into
@@ -723,9 +733,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
             cached_block
         } else {
             let block = cfg.start_new_cleanup_block();
-            cfg.terminate(block,
-                          scope.visibility_scope,
-                          drop_data.span,
+            cfg.terminate(block, source_info(drop_data.span),
                           TerminatorKind::Drop {
                               location: drop_data.location.clone(),
                               target: target,
index 5849db6bbd271f64b1789effc2b127018b88004b..8c21928c2513b9869f2f2195526c4d729cec9c4b 100644 (file)
@@ -18,7 +18,6 @@
 use std::fs;
 use std::io::{self, Write};
 use syntax::ast::NodeId;
-use syntax::codemap::Span;
 
 const INDENT: &'static str = "    ";
 /// Alignment for lining up comments following MIR statements
@@ -180,7 +179,7 @@ fn write_basic_block(tcx: TyCtxt,
         writeln!(w, "{0:1$} // {2}",
                  indented_mir,
                  ALIGN,
-                 comment(tcx, statement.scope, statement.span))?;
+                 comment(tcx, statement.source_info))?;
 
         current_location.statement_index += 1;
     }
@@ -190,12 +189,12 @@ fn write_basic_block(tcx: TyCtxt,
     writeln!(w, "{0:1$} // {2}",
              indented_terminator,
              ALIGN,
-             comment(tcx, data.terminator().scope, data.terminator().span))?;
+             comment(tcx, data.terminator().source_info))?;
 
     writeln!(w, "{}}}\n", INDENT)
 }
 
-fn comment(tcx: TyCtxt, scope: VisibilityScope, span: Span) -> String {
+fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String {
     format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
 }
 
@@ -221,7 +220,7 @@ fn write_scope_tree(tcx: TyCtxt,
         // User variable types (including the user's name in a comment).
         for (i, var) in mir.var_decls.iter().enumerate() {
             // Skip if not declared in this scope.
-            if var.scope != child {
+            if var.source_info.scope != child {
                 continue;
             }
 
@@ -242,7 +241,7 @@ fn write_scope_tree(tcx: TyCtxt,
                      indented_var,
                      ALIGN,
                      var.name,
-                     comment(tcx, var.scope, var.span))?;
+                     comment(tcx, var.source_info))?;
         }
 
         write_scope_tree(tcx, mir, scope_tree, w, child, depth + 1)?;
index bcdd62c189972021ccd58054817af3cb0b83ba3d..a90d8e93a50e627069727fd296ff1eaa5f0efe6a 100644 (file)
@@ -66,15 +66,14 @@ fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mu
                         destination: Some((_, ref mut destination)),
                         cleanup: Some(_),
                         ..
-                    }, span, scope
+                    }, source_info
                 }) if pred_count[destination.index()] > 1 => {
                     // It's a critical edge, break it
                     let call_guard = BasicBlockData {
                         statements: vec![],
                         is_cleanup: data.is_cleanup,
                         terminator: Some(Terminator {
-                            span: span,
-                            scope: scope,
+                            source_info: source_info,
                             kind: TerminatorKind::Goto { target: *destination }
                         })
                     };
index 0a533d6e289b3cbd761eddb8bb0b7d280dcda378..c9c574966c767f01703ec3602ff81ae0dcabe2c1 100644 (file)
@@ -117,18 +117,16 @@ fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
         }
     }
 
+    fn visit_source_info(&mut self, source_info: &SourceInfo) {
+        self.span = source_info.span;
+    }
+
     fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>) {
         assert_eq!(self.location.block, bb);
-        self.span = statement.span;
         self.super_statement(bb, statement);
         self.location.statement_index += 1;
     }
 
-    fn visit_terminator(&mut self, bb: BasicBlock, terminator: &Terminator<'tcx>) {
-        self.span = terminator.span;
-        self.super_terminator(bb, terminator);
-    }
-
     fn visit_basic_block_data(&mut self, bb: BasicBlock, data: &BasicBlockData<'tcx>) {
         self.location.statement_index = 0;
         self.location.block = bb;
@@ -167,8 +165,10 @@ fn new_block(&mut self) -> BasicBlock {
         self.promoted.basic_blocks.push(BasicBlockData {
             statements: vec![],
             terminator: Some(Terminator {
-                span: self.promoted.span,
-                scope: VisibilityScope::new(0),
+                source_info: SourceInfo {
+                    span: self.promoted.span,
+                    scope: ARGUMENT_VISIBILITY_SCOPE
+                },
                 kind: TerminatorKind::Return
             }),
             is_cleanup: false
@@ -179,8 +179,10 @@ fn new_block(&mut self) -> BasicBlock {
     fn assign(&mut self, dest: Lvalue<'tcx>, rvalue: Rvalue<'tcx>, span: Span) {
         let data = self.promoted.basic_blocks.last_mut().unwrap();
         data.statements.push(Statement {
-            span: span,
-            scope: VisibilityScope::new(0),
+            source_info: SourceInfo {
+                span: span,
+                scope: ARGUMENT_VISIBILITY_SCOPE
+            },
             kind: StatementKind::Assign(dest, rvalue)
         });
     }
@@ -214,7 +216,7 @@ fn promote_temp(&mut self, index: u32) -> u32 {
         // First, take the Rvalue or Call out of the source MIR,
         // or duplicate it, depending on keep_original.
         let (mut rvalue, mut call) = (None, None);
-        let span = if stmt_idx < no_stmts {
+        let source_info = if stmt_idx < no_stmts {
             let statement = &mut self.source[bb].statements[stmt_idx];
             let StatementKind::Assign(_, ref mut rhs) = statement.kind;
             if self.keep_original {
@@ -223,11 +225,11 @@ fn promote_temp(&mut self, index: u32) -> u32 {
                 let unit = Rvalue::Aggregate(AggregateKind::Tuple, vec![]);
                 rvalue = Some(mem::replace(rhs, unit));
             }
-            statement.span
+            statement.source_info
         } else if self.keep_original {
             let terminator = self.source[bb].terminator().clone();
             call = Some(terminator.kind);
-            terminator.span
+            terminator.source_info
         } else {
             let terminator = self.source[bb].terminator_mut();
             let target = match terminator.kind {
@@ -242,13 +244,13 @@ fn promote_temp(&mut self, index: u32) -> u32 {
                     dest.take().unwrap().1
                 }
                 ref kind => {
-                    span_bug!(terminator.span, "{:?} not promotable", kind);
+                    span_bug!(terminator.source_info.span, "{:?} not promotable", kind);
                 }
             };
             call = Some(mem::replace(&mut terminator.kind, TerminatorKind::Goto {
                 target: target
             }));
-            terminator.span
+            terminator.source_info
         };
 
         // Then, recurse for components in the Rvalue or Call.
@@ -266,7 +268,7 @@ fn promote_temp(&mut self, index: u32) -> u32 {
 
         // Inject the Rvalue or Call into the promoted MIR.
         if stmt_idx < no_stmts {
-            self.assign(new_temp, rvalue.unwrap(), span);
+            self.assign(new_temp, rvalue.unwrap(), source_info.span);
         } else {
             let last = self.promoted.basic_blocks.len() - 1;
             let new_target = self.new_block();
@@ -278,7 +280,7 @@ fn promote_temp(&mut self, index: u32) -> u32 {
                 _ => bug!()
             }
             let terminator = &mut self.promoted.basic_blocks[last].terminator_mut();
-            terminator.span = span;
+            terminator.source_info.span = source_info.span;
             terminator.kind = call;
         }
 
@@ -346,7 +348,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
                         continue;
                     }
                 }
-                (statement.span, mir.lvalue_ty(tcx, dest).to_ty(tcx))
+                (statement.source_info.span, mir.lvalue_ty(tcx, dest).to_ty(tcx))
             }
             Candidate::ShuffleIndices(bb) => {
                 let terminator = mir[bb].terminator();
@@ -355,11 +357,11 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
                         mir.operand_ty(tcx, &args[2])
                     }
                     _ => {
-                        span_bug!(terminator.span,
+                        span_bug!(terminator.source_info.span,
                                   "expected simd_shuffleN call to promote");
                     }
                 };
-                (terminator.span, ty)
+                (terminator.source_info.span, ty)
             }
         };
 
index b9eec6ecd9c5890260911d971a404a8ce0d30586..92ac9b049f1276203f8da77d0cc62d90f76368e4 100644 (file)
@@ -377,11 +377,12 @@ fn qualify_const(&mut self) -> Qualif {
                             let stmt_idx = location.statement_index;
 
                             // Get the span for the initialization.
-                            if stmt_idx < data.statements.len() {
-                                self.span = data.statements[stmt_idx].span;
+                            let source_info = if stmt_idx < data.statements.len() {
+                                data.statements[stmt_idx].source_info
                             } else {
-                                self.span = data.terminator().span;
-                            }
+                                data.terminator().source_info
+                            };
+                            self.span = source_info.span;
 
                             // Treat this as a statement in the AST.
                             self.statement_like();
@@ -830,7 +831,7 @@ fn visit_assign(&mut self, _: BasicBlock, dest: &Lvalue<'tcx>, rvalue: &Rvalue<'
                 // Avoid a generic error for other uses of arguments.
                 if self.qualif.intersects(Qualif::FN_ARGUMENT) {
                     let decl = &self.mir.var_decls[index as usize];
-                    span_err!(self.tcx.sess, decl.span, E0022,
+                    span_err!(self.tcx.sess, decl.source_info.span, E0022,
                               "arguments of constant functions can only \
                                be immutable by-value bindings");
                     return;
@@ -841,16 +842,18 @@ fn visit_assign(&mut self, _: BasicBlock, dest: &Lvalue<'tcx>, rvalue: &Rvalue<'
         self.assign(dest);
     }
 
+    fn visit_source_info(&mut self, source_info: &SourceInfo) {
+        self.span = source_info.span;
+    }
+
     fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>) {
         assert_eq!(self.location.block, bb);
-        self.span = statement.span;
         self.nest(|this| this.super_statement(bb, statement));
         self.location.statement_index += 1;
     }
 
     fn visit_terminator(&mut self, bb: BasicBlock, terminator: &Terminator<'tcx>) {
         assert_eq!(self.location.block, bb);
-        self.span = terminator.span;
         self.nest(|this| this.super_terminator(bb, terminator));
     }
 
index 019ed670d1f83d16cec395d97deec990a4c77faa..4bfa3b16efa16124400b319de13a9940eb69f7a9 100644 (file)
@@ -551,7 +551,7 @@ fn check_box_free_inputs(&self,
     fn check_iscleanup(&mut self, mir: &Mir<'tcx>, block: &BasicBlockData<'tcx>)
     {
         let is_cleanup = block.is_cleanup;
-        self.last_span = block.terminator().span;
+        self.last_span = block.terminator().source_info.span;
         match block.terminator().kind {
             TerminatorKind::Goto { target } =>
                 self.assert_iscleanup(mir, block, target, is_cleanup),
@@ -617,8 +617,8 @@ fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
         debug!("run_on_mir: {:?}", mir.span);
         for block in &mir.basic_blocks {
             for stmt in &block.statements {
-                if stmt.span != DUMMY_SP {
-                    self.last_span = stmt.span;
+                if stmt.source_info.span != DUMMY_SP {
+                    self.last_span = stmt.source_info.span;
                 }
                 self.check_stmt(mir, stmt);
             }
index 2c23be02ddcf35fbbcfb4b49d4cdf975ab8bdf2a..f75f973f68aabd4932621a520ced6c8d2fd3be24 100644 (file)
@@ -84,7 +84,7 @@ pub fn create_mir_scopes(fcx: &FunctionContext) -> Vec<DIScope> {
     // Find all the scopes with variables defined in them.
     let mut has_variables = BitVector::new(mir.visibility_scopes.len());
     for var in &mir.var_decls {
-        has_variables.insert(var.scope.index());
+        has_variables.insert(var.source_info.scope.index());
     }
 
     // Instantiate all scopes.
index b7aca4c8d7fed0fcd304cc8ded79840a7ac55fb0..e19f20bba1d2db6b10834468241b13ab004c5c8d 100644 (file)
@@ -108,8 +108,8 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
         let terminator = data.terminator();
         debug!("trans_block: terminator: {:?}", terminator);
 
-        let debug_loc = DebugLoc::ScopeAt(self.scopes[terminator.scope.index()],
-                                          terminator.span);
+        let span = terminator.source_info.span;
+        let debug_loc = self.debug_loc(terminator.source_info);
         debug_loc.apply_to_bcx(&bcx);
         debug_loc.apply(bcx.fcx());
         match terminator.kind {
@@ -247,7 +247,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
                 bcx = panic_block.build();
 
                 // Get the location information.
-                let loc = bcx.sess().codemap().lookup_char_pos(terminator.span.lo);
+                let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
                 let filename = token::intern_and_get_ident(&loc.file.name);
                 let filename = C_str_slice(bcx.ccx(), filename);
                 let line = C_u32(bcx.ccx(), loc.line as u32);
@@ -298,15 +298,14 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
                 // is also constant, then we can produce a warning.
                 if const_cond == Some(!expected) {
                     if let Some(err) = const_err {
-                        let _ = consts::const_err(bcx.ccx(),
-                                                  terminator.span,
+                        let _ = consts::const_err(bcx.ccx(), span,
                                                   Err::<(), _>(err),
                                                   consts::TrueConst::No);
                     }
                 }
 
                 // Obtain the panic entry point.
-                let def_id = common::langcall(bcx.tcx(), Some(terminator.span), "", lang_item);
+                let def_id = common::langcall(bcx.tcx(), Some(span), "", lang_item);
                 let callee = Callee::def(bcx.ccx(), def_id,
                     bcx.ccx().empty_substs_for_def_id(def_id));
                 let llfn = callee.reify(bcx.ccx()).val;
@@ -419,8 +418,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
                     if is_shuffle && idx == 2 {
                         match *arg {
                             mir::Operand::Consume(_) => {
-                                span_bug!(terminator.span,
-                                          "shuffle indices must be constant");
+                                span_bug!(span, "shuffle indices must be constant");
                             }
                             mir::Operand::Constant(ref constant) => {
                                 let val = self.trans_constant(&bcx, constant);
index 0cfb14955fc3f7ce531515aed94b85fa4f2d07f3..4aa6aadb2706e1c6b53a169163db9eb42cfb062e 100644 (file)
@@ -281,12 +281,13 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalFailure> {
         loop {
             let data = self.mir.basic_block_data(bb);
             for statement in &data.statements {
+                let span = statement.source_info.span;
                 match statement.kind {
                     mir::StatementKind::Assign(ref dest, ref rvalue) => {
                         let ty = self.mir.lvalue_ty(tcx, dest);
                         let ty = self.monomorphize(&ty).to_ty(tcx);
-                        match self.const_rvalue(rvalue, ty, statement.span) {
-                            Ok(value) => self.store(dest, value, statement.span),
+                        match self.const_rvalue(rvalue, ty, span) {
+                            Ok(value) => self.store(dest, value, span),
                             Err(err) => if failure.is_ok() { failure = Err(err); }
                         }
                     }
@@ -294,7 +295,7 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalFailure> {
             }
 
             let terminator = data.terminator();
-            let span = terminator.span;
+            let span = terminator.source_info.span;
             bb = match terminator.kind {
                 mir::TerminatorKind::Drop { target, .. } | // No dropping.
                 mir::TerminatorKind::Goto { target } => target,
index a6174cd4d371c4428408185ed1ce51c6650d7eea..4520bc6137cc0cabc8ccd65ca8d1272b58cf3336 100644 (file)
@@ -112,6 +112,12 @@ pub struct MirContext<'bcx, 'tcx:'bcx> {
     scopes: Vec<DIScope>
 }
 
+impl<'blk, 'tcx> MirContext<'blk, 'tcx> {
+    pub fn debug_loc(&self, source_info: mir::SourceInfo) -> DebugLoc {
+        DebugLoc::ScopeAt(self.scopes[source_info.scope.index()], source_info.span)
+    }
+}
+
 enum TempRef<'tcx> {
     Lvalue(LvalueRef<'tcx>),
     Operand(Option<OperandRef<'tcx>>),
@@ -161,12 +167,12 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
                             .map(|(mty, decl)| {
         let lvalue = LvalueRef::alloca(&bcx, mty, &decl.name.as_str());
 
-        let scope = scopes[decl.scope.index()];
+        let scope = scopes[decl.source_info.scope.index()];
         if !scope.is_null() && bcx.sess().opts.debuginfo == FullDebugInfo {
             bcx.with_block(|bcx| {
                 declare_local(bcx, decl.name, mty, scope,
                               VariableAccess::DirectVariable { alloca: lvalue.llval },
-                              VariableKind::LocalVariable, decl.span);
+                              VariableKind::LocalVariable, decl.source_info.span);
             });
         }
 
index c9a4e540fa06b92948239af8c0bb3eef96351a99..544c47e471fd3666eb45ac3e3dfe4c17546bebbe 100644 (file)
@@ -10,7 +10,6 @@
 
 use rustc::mir::repr as mir;
 use common::{self, BlockAndBuilder};
-use debuginfo::DebugLoc;
 
 use super::MirContext;
 use super::TempRef;
@@ -22,8 +21,7 @@ pub fn trans_statement(&mut self,
                            -> BlockAndBuilder<'bcx, 'tcx> {
         debug!("trans_statement(statement={:?})", statement);
 
-        let debug_loc = DebugLoc::ScopeAt(self.scopes[statement.scope.index()],
-                                          statement.span);
+        let debug_loc = self.debug_loc(statement.source_info);
         debug_loc.apply_to_bcx(&bcx);
         debug_loc.apply(bcx.fcx());
         match statement.kind {
@@ -46,7 +44,7 @@ pub fn trans_statement(&mut self,
                                 let ty = bcx.monomorphize(&ty.to_ty(bcx.tcx()));
 
                                 if !common::type_is_zero_size(bcx.ccx(), ty) {
-                                    span_bug!(statement.span,
+                                    span_bug!(statement.source_info.span,
                                               "operand {:?} already assigned",
                                               rvalue);
                                 } else {