From 0c5930ef256131f8d0e4f020a5029a89944cf250 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 7 Jun 2016 19:21:56 +0300 Subject: [PATCH] mir: group span + visibility scope under a new SourceInfo type. --- src/librustc/mir/repr.rs | 25 +++++--- src/librustc/mir/visit.rs | 33 ++++++---- .../borrowck/mir/dataflow/sanity_check.rs | 4 +- .../borrowck/mir/elaborate_drops.rs | 35 ++++------ src/librustc_borrowck/borrowck/mir/patch.rs | 22 +++---- src/librustc_mir/build/block.rs | 4 +- src/librustc_mir/build/cfg.rs | 23 +++---- src/librustc_mir/build/expr/as_lvalue.rs | 6 +- src/librustc_mir/build/expr/as_rvalue.rs | 18 +++--- src/librustc_mir/build/expr/as_temp.rs | 4 +- src/librustc_mir/build/expr/into.rs | 51 +++++---------- src/librustc_mir/build/expr/stmt.rs | 11 ++-- src/librustc_mir/build/matches/mod.rs | 50 +++++++-------- src/librustc_mir/build/matches/test.rs | 34 ++++------ src/librustc_mir/build/matches/util.rs | 4 +- src/librustc_mir/build/misc.rs | 7 +- src/librustc_mir/build/mod.rs | 12 ++-- src/librustc_mir/build/scope.rs | 64 +++++++++++-------- src/librustc_mir/pretty.rs | 11 ++-- src/librustc_mir/transform/add_call_guards.rs | 5 +- src/librustc_mir/transform/promote_consts.rs | 42 ++++++------ src/librustc_mir/transform/qualify_consts.rs | 17 +++-- src/librustc_mir/transform/type_check.rs | 6 +- .../debuginfo/create_scope_map.rs | 2 +- src/librustc_trans/mir/block.rs | 14 ++-- src/librustc_trans/mir/constant.rs | 7 +- src/librustc_trans/mir/mod.rs | 10 ++- src/librustc_trans/mir/statement.rs | 6 +- 28 files changed, 255 insertions(+), 272 deletions(-) diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 0d9c46461619d..e6c22d0ea3446 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -100,6 +100,18 @@ impl<'tcx> IndexMut for Mir<'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>, } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index d340695761de0..dbe48d6b09447 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -186,6 +186,11 @@ macro_rules! make_mir_visitor { 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 @@ macro_rules! make_mir_visitor { 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 @@ macro_rules! make_mir_visitor { 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 @@ macro_rules! make_mir_visitor { 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 @@ macro_rules! make_mir_visitor { 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) => { diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs index 74dc921b0bba5..8c528f10b57ba 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs @@ -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>) -> 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)); } } } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index e783420fa065c..b09db70e7b88a 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, '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 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { 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()); diff --git a/src/librustc_borrowck/borrowck/mir/patch.rs b/src/librustc_borrowck/borrowck/mir/patch.rs index b390c19af1a5b..b838881251da3 100644 --- a/src/librustc_borrowck/borrowck/mir/patch.rs +++ b/src/librustc_borrowck/borrowck/mir/patch.rs @@ -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 @@ impl<'tcx> MirPatch<'tcx> { 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 @@ impl<'tcx> MirPatch<'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) } } diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index f4e4b78b64677..7e650c5bd3d06 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -83,8 +83,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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. diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index 4045497575d3c..95f87bf832614 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -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 @@ impl<'tcx> CFG<'tcx> { 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, }); } diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index 1f78071dfcea4..8e33cfa9b0b52 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -34,8 +34,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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 <, Rvalue::BinaryOp(BinOp::Lt, idx.clone(), Operand::Consume(len.clone()))); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 19a3bc4d0e91e..6524124c13b06 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -41,8 +41,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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> { - 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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, diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 2a28f33180198..da128b8dd5626 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -49,8 +49,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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)); diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index fb77fc50f8686..fd9ddc05ab5c4 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -33,7 +33,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }); 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }); 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() } } diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index add268d394ab7..ad55a3d8b73f2 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // (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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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)); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 46c907009a379..6104679d6500f 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -89,18 +89,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { mut otherwise: Vec) -> 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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); diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 09c146537e7d4..1f0c4bd9e0dd6 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -176,7 +176,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { lvalue: &Lvalue<'tcx>, test: &Test<'tcx>) -> Vec { - 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }).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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } }; - self.cfg.terminate(block, - scope_id, - test.span, - term); + self.cfg.terminate(block, source_info, term); targets } @@ -265,7 +262,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }); 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 = - 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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) }); diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index 5eb58f7612d74..2e9cc96c04681 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -65,8 +65,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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)); } diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index a6294406ea567..a9d5c0c4f85c3 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -103,16 +103,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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), }); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 27cced2ae1ac7..9c1b9fa4437e0 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -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() diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 93ca01ba2ec4a..2b7efa52cbd05 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -207,6 +207,14 @@ impl<'tcx> Scope<'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { .next() .unwrap(); self.cfg.terminate(block, - scope.visibility_scope, - span, + scope.source_info(span), TerminatorKind::Goto { target: target }); } @@ -372,8 +379,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }.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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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, diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index 5849db6bbd271..8c21928c2513b 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -18,7 +18,6 @@ use std::fmt::Display; 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)?; diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index bcdd62c189972..a90d8e93a50e6 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -66,15 +66,14 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards { 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 } }) }; diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 0a533d6e289b3..c9c574966c767 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -117,18 +117,16 @@ impl<'tcx> Visitor<'tcx> for TempCollector { } } + 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { _ => 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) } }; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index b9eec6ecd9c58..92ac9b049f127 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -377,11 +377,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { 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 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // 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 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { 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)); } diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 019ed670d1f83..4bfa3b16efa16 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -551,7 +551,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, '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); } diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index 2c23be02ddcf3..f75f973f68aab 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -84,7 +84,7 @@ pub fn create_mir_scopes(fcx: &FunctionContext) -> Vec { // 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. diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index b7aca4c8d7fed..e19f20bba1d2d 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -108,8 +108,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { 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 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { 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 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { // 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 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { 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); diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 0cfb14955fc3f..4aa6aadb2706e 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -281,12 +281,13 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } 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, diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index a6174cd4d371c..4520bc6137cc0 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -112,6 +112,12 @@ pub struct MirContext<'bcx, 'tcx:'bcx> { scopes: Vec } +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>), @@ -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); }); } diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index c9a4e540fa06b..544c47e471fd3 100644 --- a/src/librustc_trans/mir/statement.rs +++ b/src/librustc_trans/mir/statement.rs @@ -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 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { -> 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 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { 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 {