summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/mir/pretty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/mir/pretty.rs')
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs73
1 files changed, 44 insertions, 29 deletions
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 05dcfba77..2a4ff4b88 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -12,11 +12,10 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId;
use rustc_index::vec::Idx;
use rustc_middle::mir::interpret::{
- read_target_uint, AllocId, Allocation, ConstAllocation, ConstValue, GlobalAlloc, Pointer,
- Provenance,
+ alloc_range, read_target_uint, AllocId, Allocation, ConstAllocation, ConstValue, GlobalAlloc,
+ Pointer, Provenance,
};
use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::MirSource;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
use rustc_target::abi::Size;
@@ -74,7 +73,7 @@ pub enum PassWhere {
#[inline]
pub fn dump_mir<'tcx, F>(
tcx: TyCtxt<'tcx>,
- pass_num: Option<&dyn Display>,
+ pass_num: bool,
pass_name: &str,
disambiguator: &dyn Display,
body: &Body<'tcx>,
@@ -111,7 +110,7 @@ pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) ->
fn dump_matched_mir_node<'tcx, F>(
tcx: TyCtxt<'tcx>,
- pass_num: Option<&dyn Display>,
+ pass_num: bool,
pass_name: &str,
disambiguator: &dyn Display,
body: &Body<'tcx>,
@@ -120,8 +119,7 @@ fn dump_matched_mir_node<'tcx, F>(
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
{
let _: io::Result<()> = try {
- let mut file =
- create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, body.source)?;
+ let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, body)?;
// see notes on #41697 above
let def_path =
ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id()));
@@ -143,16 +141,14 @@ fn dump_matched_mir_node<'tcx, F>(
if tcx.sess.opts.unstable_opts.dump_mir_graphviz {
let _: io::Result<()> = try {
- let mut file =
- create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, body.source)?;
+ let mut file = create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, body)?;
write_mir_fn_graphviz(tcx, body, false, &mut file)?;
};
}
if let Some(spanview) = tcx.sess.opts.unstable_opts.dump_mir_spanview {
let _: io::Result<()> = try {
- let file_basename =
- dump_file_basename(tcx, pass_num, pass_name, disambiguator, body.source);
+ let file_basename = dump_file_basename(tcx, pass_num, pass_name, disambiguator, body);
let mut file = create_dump_file_with_basename(tcx, &file_basename, "html")?;
if body.source.def_id().is_local() {
write_mir_fn_spanview(tcx, body, spanview, &file_basename, &mut file)?;
@@ -165,11 +161,12 @@ fn dump_matched_mir_node<'tcx, F>(
/// where we should dump a MIR representation output files.
fn dump_file_basename<'tcx>(
tcx: TyCtxt<'tcx>,
- pass_num: Option<&dyn Display>,
+ pass_num: bool,
pass_name: &str,
disambiguator: &dyn Display,
- source: MirSource<'tcx>,
+ body: &Body<'tcx>,
) -> String {
+ let source = body.source;
let promotion_id = match source.promoted {
Some(id) => format!("-{:?}", id),
None => String::new(),
@@ -178,9 +175,10 @@ fn dump_file_basename<'tcx>(
let pass_num = if tcx.sess.opts.unstable_opts.dump_mir_exclude_pass_number {
String::new()
} else {
- match pass_num {
- None => ".-------".to_string(),
- Some(pass_num) => format!(".{}", pass_num),
+ if pass_num {
+ format!(".{:03}-{:03}", body.phase.phase_index(), body.pass_count)
+ } else {
+ ".-------".to_string()
}
};
@@ -250,14 +248,14 @@ fn create_dump_file_with_basename(
pub fn create_dump_file<'tcx>(
tcx: TyCtxt<'tcx>,
extension: &str,
- pass_num: Option<&dyn Display>,
+ pass_num: bool,
pass_name: &str,
disambiguator: &dyn Display,
- source: MirSource<'tcx>,
+ body: &Body<'tcx>,
) -> io::Result<io::BufWriter<fs::File>> {
create_dump_file_with_basename(
tcx,
- &dump_file_basename(tcx, pass_num, pass_name, disambiguator, source),
+ &dump_file_basename(tcx, pass_num, pass_name, disambiguator, body),
extension,
)
}
@@ -476,6 +474,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
// These variants shouldn't exist in the MIR.
ty::ConstKind::Placeholder(_)
| ty::ConstKind::Infer(_)
+ | ty::ConstKind::Expr(_)
| ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal),
},
ConstantKind::Unevaluated(uv, _) => {
@@ -685,7 +684,7 @@ pub fn write_allocations<'tcx>(
fn alloc_ids_from_alloc(
alloc: ConstAllocation<'_>,
) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
- alloc.inner().provenance().values().map(|id| *id)
+ alloc.inner().provenance().ptrs().values().map(|id| *id)
}
fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
@@ -788,7 +787,7 @@ pub fn write_allocations<'tcx>(
/// After the hex dump, an ascii dump follows, replacing all unprintable characters (control
/// characters or characters whose value is larger than 127) with a `.`
/// This also prints provenance adequately.
-pub fn display_allocation<'a, 'tcx, Prov, Extra>(
+pub fn display_allocation<'a, 'tcx, Prov: Provenance, Extra>(
tcx: TyCtxt<'tcx>,
alloc: &'a Allocation<Prov, Extra>,
) -> RenderAllocation<'a, 'tcx, Prov, Extra> {
@@ -796,7 +795,7 @@ pub fn display_allocation<'a, 'tcx, Prov, Extra>(
}
#[doc(hidden)]
-pub struct RenderAllocation<'a, 'tcx, Prov, Extra> {
+pub struct RenderAllocation<'a, 'tcx, Prov: Provenance, Extra> {
tcx: TyCtxt<'tcx>,
alloc: &'a Allocation<Prov, Extra>,
}
@@ -882,9 +881,9 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
if i != line_start {
write!(w, " ")?;
}
- if let Some(&prov) = alloc.provenance().get(&i) {
+ if let Some(prov) = alloc.provenance().get_ptr(i) {
// Memory with provenance must be defined
- assert!(alloc.init_mask().is_range_initialized(i, i + ptr_size).is_ok());
+ assert!(alloc.init_mask().is_range_initialized(alloc_range(i, ptr_size)).is_ok());
let j = i.bytes_usize();
let offset = alloc
.inspect_with_uninit_and_ptr_outside_interpreter(j..j + ptr_size.bytes_usize());
@@ -904,9 +903,9 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
let overflow = ptr_size - remainder;
let remainder_width = provenance_width(remainder.bytes_usize()) - 2;
let overflow_width = provenance_width(overflow.bytes_usize() - 1) + 1;
- ascii.push('╾');
- for _ in 0..remainder.bytes() - 1 {
- ascii.push('─');
+ ascii.push('╾'); // HEAVY LEFT AND LIGHT RIGHT
+ for _ in 1..remainder.bytes() {
+ ascii.push('─'); // LIGHT HORIZONTAL
}
if overflow_width > remainder_width && overflow_width >= target.len() {
// The case where the provenance fits into the part in the next line
@@ -926,7 +925,7 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
for _ in 0..overflow.bytes() - 1 {
ascii.push('─');
}
- ascii.push('╼');
+ ascii.push('╼'); // LIGHT LEFT AND HEAVY RIGHT
i += ptr_size;
continue;
} else {
@@ -941,7 +940,23 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>(
ascii.push('╼');
i += ptr_size;
}
- } else if alloc.init_mask().is_range_initialized(i, i + Size::from_bytes(1)).is_ok() {
+ } else if let Some(prov) = alloc.provenance().get(i, &tcx) {
+ // Memory with provenance must be defined
+ assert!(
+ alloc.init_mask().is_range_initialized(alloc_range(i, Size::from_bytes(1))).is_ok()
+ );
+ ascii.push('━'); // HEAVY HORIZONTAL
+ // We have two characters to display this, which is obviously not enough.
+ // Format is similar to "oversized" above.
+ let j = i.bytes_usize();
+ let c = alloc.inspect_with_uninit_and_ptr_outside_interpreter(j..j + 1)[0];
+ write!(w, "╾{:02x}{:#?} (1 ptr byte)╼", c, prov)?;
+ i += Size::from_bytes(1);
+ } else if alloc
+ .init_mask()
+ .is_range_initialized(alloc_range(i, Size::from_bytes(1)))
+ .is_ok()
+ {
let j = i.bytes_usize();
// Checked definedness (and thus range) and provenance. This access also doesn't