Skip to content
Permalink
Browse files

rustc_mir: pretty-print all locals into their respective scopes.

  • Loading branch information...
eddyb committed May 17, 2018
1 parent d20da13 commit 9260305c9e6a15c7692b85324afbd7b36afb29ed
@@ -461,9 +461,7 @@ fn comment(tcx: TyCtxt<'_, '_, '_>, SourceInfo { span, scope }: SourceInfo) -> S
)
}

/// Prints user-defined variables in a scope tree.
///
/// Returns the total number of variables printed.
/// Prints local variables in a scope tree.
fn write_scope_tree(
tcx: TyCtxt<'_, '_, '_>,
mir: &Mir<'_>,
@@ -474,57 +472,64 @@ fn write_scope_tree(
) -> io::Result<()> {
let indent = depth * INDENT.len();

// Local variable types (including the user's name in a comment).
for (local, local_decl) in mir.local_decls.iter_enumerated() {
if (1..mir.arg_count+1).contains(&local.index()) {
// Skip over argument locals, they're printed in the signature.
continue;
}

if local_decl.source_info.scope != parent {
// Not declared in this scope.
continue;
}

let mut_str = if local_decl.mutability == Mutability::Mut {
"mut "
} else {
""
};

let mut indented_decl = format!(
"{0:1$}let {2}{3:?}: {4:?}",
INDENT,
indent,
mut_str,
local,
local_decl.ty
);
for user_ty in local_decl.user_ty.projections() {
write!(indented_decl, " as {:?}", user_ty).unwrap();
}
indented_decl.push_str(";");

let local_name = if local == RETURN_PLACE {
format!(" return place")
} else if let Some(name) = local_decl.name {
format!(" \"{}\"", name)
} else {
String::new()
};

writeln!(
w,
"{0:1$} //{2} in {3}",
indented_decl,
ALIGN,
local_name,
comment(tcx, local_decl.source_info),
)?;
}

let children = match scope_tree.get(&parent) {
Some(children) => children,
Some(childs) => childs,
None => return Ok(()),
};

for &child in children {
let data = &mir.source_scopes[child];
assert_eq!(data.parent_scope, Some(parent));
assert_eq!(mir.source_scopes[child].parent_scope, Some(parent));
writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?;

// User variable types (including the user's name in a comment).
for local in mir.vars_iter() {
let var = &mir.local_decls[local];
let (name, source_info) = if var.source_info.scope == child {
(var.name.unwrap(), var.source_info)
} else {
// Not a variable or not declared in this scope.
continue;
};

let mut_str = if var.mutability == Mutability::Mut {
"mut "
} else {
""
};

let indent = indent + INDENT.len();
let mut indented_var = format!(
"{0:1$}let {2}{3:?}: {4:?}",
INDENT,
indent,
mut_str,
local,
var.ty
);
for user_ty in var.user_ty.projections() {
write!(indented_var, " as {:?}", user_ty).unwrap();
}
indented_var.push_str(";");
writeln!(
w,
"{0:1$} // \"{2}\" in {3}",
indented_var,
ALIGN,
name,
comment(tcx, source_info)
)?;
}

write_scope_tree(tcx, mir, scope_tree, w, child, depth + 1)?;

writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
}

@@ -556,19 +561,8 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(
}
}

// Print return place
let indented_retptr = format!("{}let mut {:?}: {};",
INDENT,
RETURN_PLACE,
mir.local_decls[RETURN_PLACE].ty);
writeln!(w, "{0:1$} // return place",
indented_retptr,
ALIGN)?;

write_scope_tree(tcx, mir, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?;

write_temp_decls(mir, w)?;

// Add an empty line before the first block is printed.
writeln!(w, "")?;

@@ -632,22 +626,6 @@ fn write_mir_sig(
Ok(())
}

fn write_temp_decls(mir: &Mir<'_>, w: &mut dyn Write) -> io::Result<()> {
// Compiler-introduced temporary types.
for temp in mir.temps_iter() {
writeln!(
w,
"{}let {}{:?}: {};",
INDENT,
if mir.local_decls[temp].mutability == Mutability::Mut {"mut "} else {""},
temp,
mir.local_decls[temp].ty
)?;
}

Ok(())
}

fn write_user_type_annotations(mir: &Mir<'_>, w: &mut dyn Write) -> io::Result<()> {
if !mir.user_type_annotations.is_empty() {
writeln!(w, "| User Type Annotations")?;
@@ -22,15 +22,14 @@ impl Drop for S {
// END RUST SOURCE
// START rustc.main.ElaborateDrops.before.mir
// let mut _0: ();
// let mut _2: std::boxed::Box<S>;
// let mut _3: ();
// let mut _4: std::boxed::Box<S>;
// scope 1 {
// }
// scope 2 {
// let _1: std::boxed::Box<S>;
// }
// let mut _2: std::boxed::Box<S>;
// let mut _3: ();
// let mut _4: std::boxed::Box<S>;
//
// bb0: {
// StorageLive(_1);
// StorageLive(_2);
@@ -29,27 +29,28 @@ impl S {
// END RUST SOURCE
// START rustc.main.ElaborateDrops.after.mir
// let mut _0: ();
// let mut _2: S;
// let mut _3: S;
// let mut _4: S;
// let mut _5: bool;
// scope 1 {
// }
// scope 2 {
// let _1: ();
// }
// let mut _2: S;
// let mut _3: S;
// let mut _4: S;
// let mut _5: bool;
// ...
// bb0: {
// END rustc.main.ElaborateDrops.after.mir
// START rustc.test.ElaborateDrops.after.mir
// let mut _0: ();
// let mut _3: ();
// let mut _4: S;
// let mut _5: S;
// let mut _6: bool;
// ...
// let mut _2: S;
// ...
// let _1: S;
// ...
// let mut _3: ();
// let mut _4: S;
// let mut _5: S;
// let mut _6: bool;
// bb0: {
// END rustc.test.ElaborateDrops.after.mir
@@ -17,16 +17,16 @@ fn main() {
// START rustc.main.mir_map.0.mir
// fn main() -> (){
// let mut _0: ();
// scope 1 {
// }
// scope 2 {
// let _2: i32;
// }
// let mut _1: ();
// let mut _3: bool;
// let mut _4: !;
// let mut _5: ();
// let mut _6: &i32;
// scope 1 {
// }
// scope 2 {
// let _2: i32;
// }
// bb0: {
// goto -> bb1;
// }
@@ -18,16 +18,16 @@ impl Drop for Droppy {
// START rustc.main.EraseRegions.before.mir
// fn main() -> () {
// let mut _0: ();
// scope 1 {
// }
// scope 2 {
// let mut _1: Packed;
// }
// let mut _2: Aligned;
// let mut _3: Droppy;
// let mut _4: Aligned;
// let mut _5: Droppy;
// let mut _6: Aligned;
// scope 1 {
// }
// scope 2 {
// let mut _1: Packed;
// }
//
// bb0: {
// StorageLive(_1);

0 comments on commit 9260305

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