Skip to content

Commit

Permalink
Auto merge of #33989 - eddyb:mir-viz, r=nikomatsakis
Browse files Browse the repository at this point in the history
[MIR] Make scopes debuginfo-specific (visibility scopes).

Fixes #32949 by having MIR (visibility) scopes mimic the lexical structure.
Unlike #33235, this PR also removes all scopes without variable bindings.

Printing of scopes also changed, e.g. for:
```rust
fn foo(x: i32, y: i32) { let a = 0; let b = 0; let c = 0; }
```
Before my changes:
```rust
fn foo(arg0: i32, arg1: i32) -> () {
    let var0: i32;                       // "x" in scope 1 at <anon>:1:8: 1:9
    let var1: i32;                       // "y" in scope 1 at <anon>:1:16: 1:17
    let var2: i32;                       // "a" in scope 3 at <anon>:1:30: 1:31
    let var3: i32;                       // "b" in scope 6 at <anon>:1:41: 1:42
    let var4: i32;                       // "c" in scope 9 at <anon>:1:52: 1:53

    ...

    scope tree:
    0 1 2 3 {
        4 5
        6 {
            7 8
            9 10 11
        }
    }
}
```
After my changes:
```rust
fn foo(arg0: i32, arg1: i32) -> () {
    scope 1 {
        let var0: i32;                   // "x" in scope 1 at <anon>:1:8: 1:9
        let var1: i32;                   // "y" in scope 1 at <anon>:1:16: 1:17
        scope 2 {
            let var2: i32;               // "a" in scope 2 at <anon>:1:30: 1:31
            scope 3 {
                let var3: i32;           // "b" in scope 3 at <anon>:1:41: 1:42
                scope 4 {
                    let var4: i32;       // "c" in scope 4 at <anon>:1:52: 1:53
                }
            }
        }
    }

    ...
}
  • Loading branch information
bors committed Jun 8, 2016
2 parents 4b240fe + 0c5930e commit 0d531bf
Show file tree
Hide file tree
Showing 30 changed files with 478 additions and 493 deletions.
56 changes: 33 additions & 23 deletions src/librustc/mir/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ pub struct Mir<'tcx> {
/// that indexes into this vector.
pub basic_blocks: Vec<BasicBlockData<'tcx>>,

/// List of lexical scopes; these are referenced by statements and
/// used (eventually) for debuginfo. Indexed by a `ScopeId`.
pub scopes: Vec<ScopeData>,
/// List of visibility (lexical) scopes; these are referenced by statements
/// and used (eventually) for debuginfo. Indexed by a `VisibilityScope`.
pub visibility_scopes: Vec<VisibilityScopeData>,

/// Rvalues promoted from this function, such as borrows of constants.
/// Each of them is the Mir of a constant with the fn's type parameters
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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: ScopeId,

/// 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
Expand Down Expand Up @@ -275,8 +284,7 @@ pub struct BasicBlockData<'tcx> {

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Terminator<'tcx> {
pub span: Span,
pub scope: ScopeId,
pub source_info: SourceInfo,
pub kind: TerminatorKind<'tcx>
}

Expand Down Expand Up @@ -587,8 +595,7 @@ pub enum AssertMessage<'tcx> {

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct Statement<'tcx> {
pub span: Span,
pub scope: ScopeId,
pub source_info: SourceInfo,
pub kind: StatementKind<'tcx>,
}

Expand Down Expand Up @@ -754,29 +761,32 @@ impl<'tcx> Debug for Lvalue<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Scopes

impl Index<ScopeId> for Vec<ScopeData> {
type Output = ScopeData;
impl Index<VisibilityScope> for Vec<VisibilityScopeData> {
type Output = VisibilityScopeData;

#[inline]
fn index(&self, index: ScopeId) -> &ScopeData {
fn index(&self, index: VisibilityScope) -> &VisibilityScopeData {
&self[index.index()]
}
}

impl IndexMut<ScopeId> for Vec<ScopeData> {
impl IndexMut<VisibilityScope> for Vec<VisibilityScopeData> {
#[inline]
fn index_mut(&mut self, index: ScopeId) -> &mut ScopeData {
fn index_mut(&mut self, index: VisibilityScope) -> &mut VisibilityScopeData {
&mut self[index.index()]
}
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub struct ScopeId(u32);
pub struct VisibilityScope(u32);

/// The visibility scope all arguments go into.
pub const ARGUMENT_VISIBILITY_SCOPE: VisibilityScope = VisibilityScope(0);

impl ScopeId {
pub fn new(index: usize) -> ScopeId {
impl VisibilityScope {
pub fn new(index: usize) -> VisibilityScope {
assert!(index < (u32::MAX as usize));
ScopeId(index as u32)
VisibilityScope(index as u32)
}

pub fn index(self) -> usize {
Expand All @@ -785,9 +795,9 @@ impl ScopeId {
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ScopeData {
pub struct VisibilityScopeData {
pub span: Span,
pub parent_scope: Option<ScopeId>,
pub parent_scope: Option<VisibilityScope>,
}

///////////////////////////////////////////////////////////////////////////
Expand Down
63 changes: 36 additions & 27 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ macro_rules! make_mir_visitor {
self.super_basic_block_data(block, data);
}

fn visit_scope_data(&mut self,
scope_data: & $($mutability)* ScopeData) {
self.super_scope_data(scope_data);
fn visit_visibility_scope_data(&mut self,
scope_data: & $($mutability)* VisibilityScopeData) {
self.super_visibility_scope_data(scope_data);
}

fn visit_statement(&mut self,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -236,9 +241,9 @@ macro_rules! make_mir_visitor {
self.super_arg_decl(arg_decl);
}

fn visit_scope_id(&mut self,
scope_id: & $($mutability)* ScopeId) {
self.super_scope_id(scope_id);
fn visit_visibility_scope(&mut self,
scope: & $($mutability)* VisibilityScope) {
self.super_visibility_scope(scope);
}

// The `super_xxx` methods comprise the default behavior and are
Expand All @@ -248,7 +253,7 @@ macro_rules! make_mir_visitor {
mir: & $($mutability)* Mir<'tcx>) {
let Mir {
ref $($mutability)* basic_blocks,
ref $($mutability)* scopes,
ref $($mutability)* visibility_scopes,
promoted: _, // Visited by passes separately.
ref $($mutability)* return_ty,
ref $($mutability)* var_decls,
Expand All @@ -263,8 +268,8 @@ macro_rules! make_mir_visitor {
self.visit_basic_block_data(block, data);
}

for scope in scopes {
self.visit_scope_data(scope);
for scope in visibility_scopes {
self.visit_visibility_scope_data(scope);
}

self.visit_fn_output(return_ty);
Expand Down Expand Up @@ -302,30 +307,28 @@ macro_rules! make_mir_visitor {
}
}

fn super_scope_data(&mut self,
scope_data: & $($mutability)* ScopeData) {
let ScopeData {
fn super_visibility_scope_data(&mut self,
scope_data: & $($mutability)* VisibilityScopeData) {
let VisibilityScopeData {
ref $($mutability)* span,
ref $($mutability)* parent_scope,
} = *scope_data;

self.visit_span(span);
if let Some(ref $($mutability)* parent_scope) = *parent_scope {
self.visit_scope_id(parent_scope);
self.visit_visibility_scope(parent_scope);
}
}

fn super_statement(&mut self,
block: BasicBlock,
statement: & $($mutability)* Statement<'tcx>) {
let Statement {
ref $($mutability)* span,
ref $($mutability)* scope,
ref $($mutability)* source_info,
ref $($mutability)* kind,
} = *statement;

self.visit_span(span);
self.visit_scope_id(scope);
self.visit_source_info(source_info);
match *kind {
StatementKind::Assign(ref $($mutability)* lvalue,
ref $($mutability)* rvalue) => {
Expand All @@ -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_scope_id(scope);
self.visit_source_info(source_info);
self.visit_terminator_kind(block, kind);
}

Expand Down Expand Up @@ -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_scope_id(scope);
self.visit_span(span);
self.visit_source_info(source_info);
}

fn super_temp_decl(&mut self,
Expand All @@ -651,8 +650,8 @@ macro_rules! make_mir_visitor {
self.visit_ty(ty);
}

fn super_scope_id(&mut self,
_scope_id: & $($mutability)* ScopeId) {
fn super_visibility_scope(&mut self,
_scope: & $($mutability)* VisibilityScope) {
}

fn super_branch(&mut self,
Expand Down Expand Up @@ -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) => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));
}
}
}
Expand Down
Loading

0 comments on commit 0d531bf

Please sign in to comment.