mir: group span + visibility scope under a new SourceInfo type.
This commit is contained in:
parent
719a591630
commit
0c5930ef25
@ -100,6 +100,18 @@ impl<'tcx> IndexMut<BasicBlock> 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>,
|
||||
}
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
@ -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())));
|
||||
|
@ -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<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 @@ 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,
|
||||
|
@ -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));
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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>)
|
||||
-> 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);
|
||||
|
@ -176,7 +176,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
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 @@ 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 = <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 @@ 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)
|
||||
});
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
});
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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)?;
|
||||
|
@ -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 }
|
||||
})
|
||||
};
|
||||
|
@ -117,16 +117,14 @@ impl<'tcx> Visitor<'tcx> for TempCollector {
|
||||
}
|
||||
}
|
||||
|
||||
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_source_info(&mut self, source_info: &SourceInfo) {
|
||||
self.span = source_info.span;
|
||||
}
|
||||
|
||||
fn visit_terminator(&mut self, bb: BasicBlock, terminator: &Terminator<'tcx>) {
|
||||
self.span = terminator.span;
|
||||
self.super_terminator(bb, terminator);
|
||||
fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>) {
|
||||
assert_eq!(self.location.block, bb);
|
||||
self.super_statement(bb, statement);
|
||||
self.location.statement_index += 1;
|
||||
}
|
||||
|
||||
fn visit_basic_block_data(&mut self, bb: BasicBlock, data: &BasicBlockData<'tcx>) {
|
||||
@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user