Skip to content
Permalink
Browse files

rustc: move debug info from LocalDecl and UpvarDecl into a dedicated …

…VarDebugInfo.
  • Loading branch information
eddyb committed May 16, 2018
1 parent 876a72a commit 563ed27c01c204d734355709c905f9a14246d4ff
Showing with 780 additions and 480 deletions.
  1. +24 −49 src/librustc/mir/mod.rs
  2. +28 −3 src/librustc/mir/visit.rs
  3. +2 −4 src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
  4. +80 −20 src/librustc_codegen_llvm/debuginfo/metadata.rs
  5. +82 −31 src/librustc_codegen_ssa/mir/analyze.rs
  6. +13 −126 src/librustc_codegen_ssa/mir/debuginfo.rs
  7. +3 −1 src/librustc_codegen_ssa/mir/mod.rs
  8. +51 −15 src/librustc_mir/borrow_check/conflict_errors.rs
  9. +4 −4 src/librustc_mir/borrow_check/error_reporting.rs
  10. +20 −6 src/librustc_mir/borrow_check/mod.rs
  11. +2 −2 src/librustc_mir/borrow_check/move_errors.rs
  12. +4 −5 src/librustc_mir/borrow_check/mutability_errors.rs
  13. +8 −4 src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
  14. +3 −1 src/librustc_mir/borrow_check/nll/mod.rs
  15. +19 −7 src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
  16. +18 −5 src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs
  17. +9 −5 src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
  18. +7 −4 src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs
  19. +13 −3 src/librustc_mir/borrow_check/nll/region_infer/mod.rs
  20. +0 −2 src/librustc_mir/build/expr/into.rs
  21. +14 −4 src/librustc_mir/build/matches/mod.rs
  22. +109 −77 src/librustc_mir/build/mod.rs
  23. +0 −6 src/librustc_mir/shim.rs
  24. +0 −1 src/librustc_mir/transform/const_prop.rs
  25. +2 −16 src/librustc_mir/transform/generator.rs
  26. +4 −8 src/librustc_mir/transform/inline.rs
  27. +0 −1 src/librustc_mir/transform/promote_consts.rs
  28. +0 −8 src/librustc_mir/transform/simplify.rs
  29. +1 −0 src/librustc_mir/transform/uniform_array_move_out.rs
  30. +33 −8 src/librustc_mir/util/def_use.rs
  31. +7 −7 src/librustc_mir/util/graphviz.rs
  32. +3 −0 src/librustc_mir/util/liveness.rs
  33. +24 −2 src/librustc_mir/util/pretty.rs
  34. +1 −1 src/test/incremental/hashes/for_loops.rs
  35. +4 −4 src/test/incremental/hashes/let_expressions.rs
  36. +1 −1 src/test/incremental/hashes/loop_expressions.rs
  37. +2 −2 src/test/incremental/hashes/while_loops.rs
  38. +1 −0 src/test/mir-opt/box_expr.rs
  39. +2 −0 src/test/mir-opt/generator-storage-dead-unwind.rs
  40. +38 −18 src/test/mir-opt/inline-closure-borrows-arg.rs
  41. +60 −0 src/test/mir-opt/inline-closure-captures.rs
  42. +34 −18 src/test/mir-opt/inline-closure.rs
  43. +5 −0 src/test/mir-opt/issue-41110.rs
  44. +3 −1 src/test/mir-opt/issue-41888.rs
  45. +1 −0 src/test/mir-opt/issue-49232.rs
  46. +6 −0 src/test/mir-opt/match-arm-scopes.rs
  47. +4 −0 src/test/mir-opt/nll/region-subtyping-basic.rs
  48. +1 −0 src/test/mir-opt/packed-struct-drop-aligned.rs
  49. +30 −0 src/test/mir-opt/simplify_try.rs
@@ -141,14 +141,8 @@ pub struct Body<'tcx> {
/// This is used for the "rust-call" ABI.
pub spread_arg: Option<Local>,

/// Names and capture modes of all the closure upvars, assuming
/// the first argument is either the closure or a reference to it.
//
// NOTE(eddyb) This is *strictly* a temporary hack for codegen
// debuginfo generation, and will be removed at some point.
// Do **NOT** use it for anything else; upvar information should not be
// in the MIR, so please rely on local crate HIR or other side-channels.
pub __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
/// Debug information pertaining to user variables, including captures.
pub var_debug_info: Vec<VarDebugInfo<'tcx>>,

/// Mark this MIR of a const context other than const functions as having converted a `&&` or
/// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
@@ -170,11 +164,10 @@ impl<'tcx> Body<'tcx> {
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
source_scopes: IndexVec<SourceScope, SourceScopeData>,
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
yield_ty: Option<Ty<'tcx>>,
local_decls: LocalDecls<'tcx>,
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
arg_count: usize,
__upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
var_debug_info: Vec<VarDebugInfo<'tcx>>,
span: Span,
control_flow_destroyed: Vec<(Span, String)>,
) -> Self {
@@ -191,14 +184,14 @@ impl<'tcx> Body<'tcx> {
basic_blocks,
source_scopes,
source_scope_local_data,
yield_ty,
yield_ty: None,
generator_drop: None,
generator_layout: None,
local_decls,
user_type_annotations,
arg_count,
__upvar_debuginfo_codegen_only_do_not_use,
spread_arg: None,
var_debug_info,
span,
cache: cache::Cache::new(),
control_flow_destroyed,
@@ -280,7 +273,7 @@ impl<'tcx> Body<'tcx> {
LocalKind::ReturnPointer
} else if index < self.arg_count + 1 {
LocalKind::Arg
} else if self.local_decls[local].name.is_some() {
} else if self.local_decls[local].is_user_variable() {
LocalKind::Var
} else {
LocalKind::Temp
@@ -728,12 +721,6 @@ pub struct LocalDecl<'tcx> {
// FIXME(matthewjasper) Don't store in this in `Body`
pub user_ty: UserTypeProjections,

/// The name of the local, used in debuginfo and pretty-printing.
///
/// Note that function arguments can also have this set to `Some(_)`
/// to generate better debuginfo.
pub name: Option<Name>,

/// The *syntactic* (i.e., not visibility) source scope the local is defined
/// in. If the local was defined in a let-statement, this
/// is *within* the let-statement, rather than outside
@@ -785,9 +772,9 @@ pub struct LocalDecl<'tcx> {
/// `drop(x)`, we want it to refer to `x: u32`.
///
/// To allow both uses to work, we need to have more than a single scope
/// for a local. We have the `source_info.scope` represent the
/// "syntactic" lint scope (with a variable being under its let
/// block) while the `visibility_scope` represents the "local variable"
/// for a local. We have the `source_info.scope` represent the "syntactic"
/// lint scope (with a variable being under its let block) while the
/// `var_debug_info.source_info.scope` represents the "local variable"
/// scope (where the "rest" of a block is under all prior let-statements).
///
/// The end result looks like this:
@@ -806,18 +793,14 @@ pub struct LocalDecl<'tcx> {
/// │ │
/// │ │ │{ let y: u32 }
/// │ │ │
/// │ │ │← y.visibility_scope
/// │ │ │← y.var_debug_info.source_info.scope
/// │ │ │← `y + 2`
/// │
/// │ │{ let x: u32 }
/// │ │← x.visibility_scope
/// │ │← x.var_debug_info.source_info.scope
/// │ │← `drop(x)` // This accesses `x: u32`.
/// ```
pub source_info: SourceInfo,

/// Source scope within which the local is visible (for debuginfo)
/// (see `source_info` for more details).
pub visibility_scope: SourceScope,
}

/// Extra information about a local that's used for diagnostics.
@@ -955,9 +938,7 @@ impl<'tcx> LocalDecl<'tcx> {
mutability,
ty,
user_ty: UserTypeProjections::none(),
name: None,
source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal,
local_info: LocalInfo::Other,
is_block_tail: None,
@@ -974,22 +955,27 @@ impl<'tcx> LocalDecl<'tcx> {
ty: return_ty,
user_ty: UserTypeProjections::none(),
source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal: false,
is_block_tail: None,
name: None, // FIXME maybe we do want some name here?
local_info: LocalInfo::Other,
}
}
}

/// A closure capture, with its name and mode.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct UpvarDebuginfo {
pub debug_name: Name,
/// Debug information pertaining to a user variable.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VarDebugInfo<'tcx> {
pub name: Name,

/// If true, the capture is behind a reference.
pub by_ref: bool,
/// Source info of the user variable, including the scope
/// within which the variable is visible (to debuginfo)
/// (see `LocalDecl`'s `source_info` field for more details).
pub source_info: SourceInfo,

/// Where the data for this user variable is to be found.
/// NOTE(eddyb) There's an unenforced invariant that this `Place` is
/// based on a `Local`, not a `Static`, and contains no indexing.
pub place: Place<'tcx>,
}

///////////////////////////////////////////////////////////////////////////
@@ -2758,16 +2744,6 @@ pub struct GeneratorLayout<'tcx> {
/// have conflicts with each other are allowed to overlap in the computed
/// layout.
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,

/// The names and scopes of all the stored generator locals.
///
/// N.B., this is *strictly* a temporary hack for codegen
/// debuginfo generation, and will be removed at some point.
/// Do **NOT** use it for anything else, local information should not be
/// in the MIR, please rely on local crate HIR or other side-channels.
//
// FIXME(tmandry): see above.
pub __local_debuginfo_codegen_only_do_not_use: IndexVec<GeneratorSavedLocal, LocalDecl<'tcx>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
@@ -2946,7 +2922,6 @@ CloneTypeFoldableAndLiftImpls! {
MirPhase,
Mutability,
SourceInfo,
UpvarDebuginfo,
FakeReadCause,
RetagKind,
SourceScope,
@@ -221,6 +221,11 @@ macro_rules! make_mir_visitor {
self.super_local_decl(local, local_decl);
}

fn visit_var_debug_info(&mut self,
var_debug_info: & $($mutability)* VarDebugInfo<'tcx>) {
self.super_var_debug_info(var_debug_info);
}

fn visit_local(&mut self,
_local: & $($mutability)? Local,
_context: PlaceContext,
@@ -279,6 +284,10 @@ macro_rules! make_mir_visitor {
);
}

for var_debug_info in &$($mutability)? body.var_debug_info {
self.visit_var_debug_info(var_debug_info);
}

self.visit_span(&$($mutability)? body.span);
}

@@ -687,9 +696,7 @@ macro_rules! make_mir_visitor {
mutability: _,
ty,
user_ty,
name: _,
source_info,
visibility_scope,
internal: _,
local_info: _,
is_block_tail: _,
@@ -703,7 +710,23 @@ macro_rules! make_mir_visitor {
self.visit_user_type_projection(user_ty);
}
self.visit_source_info(source_info);
self.visit_source_scope(visibility_scope);
}

fn super_var_debug_info(&mut self,
var_debug_info: & $($mutability)? VarDebugInfo<'tcx>) {
let VarDebugInfo {
name: _,
source_info,
place,
} = var_debug_info;

self.visit_source_info(source_info);
let location = START_BLOCK.start_location();
self.visit_place(
place,
PlaceContext::NonUse(NonUseContext::VarDebugInfo),
location,
);
}

fn super_source_scope(&mut self,
@@ -1029,6 +1052,8 @@ pub enum NonUseContext {
StorageDead,
/// User type annotation assertions for NLL.
AscribeUserTy,
/// The data of an user variable, for debug info.
VarDebugInfo,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -23,12 +23,10 @@ pub fn compute_mir_scopes(
) {
// Find all the scopes with variables defined in them.
let mut has_variables = BitSet::new_empty(mir.source_scopes.len());
// FIXME(eddyb) base this on `decl.name`, or even better, on debuginfo.
// FIXME(eddyb) take into account that arguments always have debuginfo,
// irrespective of their name (assuming full debuginfo is enabled).
for var in mir.vars_iter() {
let decl = &mir.local_decls[var];
has_variables.insert(decl.visibility_scope);
for var_debug_info in &mir.var_debug_info {
has_variables.insert(var_debug_info.source_info.scope);
}

// Instantiate all scopes.

0 comments on commit 563ed27

Please sign in to comment.
You can’t perform that action at this time.