about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-09-14 23:33:42 +0200
committerRalf Jung <post@ralfj.de>2023-09-19 11:06:32 +0200
commit10a822be385be021ee717adad58b6290f149d829 (patch)
treef308481d0a4cc63f45243a51a0e138b8b423398b
parent49f5b17cdb79548a4eef69b7a5559fbd4e1a946d (diff)
downloadrust-10a822be385be021ee717adad58b6290f149d829.tar.gz
rust-10a822be385be021ee717adad58b6290f149d829.zip
move some MIR const pretty-printing into pretty.rs
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs181
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs153
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs15
4 files changed, 176 insertions, 177 deletions
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 92c6828a0b4..c80419d4c09 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -7,8 +7,8 @@ use rustc_span::Span;
 use rustc_target::abi::Size;
 
 use crate::mir::interpret::{ConstValue, ErrorHandled, GlobalAlloc, Scalar};
-use crate::mir::{interpret, pretty_print_const, pretty_print_const_value, Promoted};
-use crate::ty::{self, List, Ty, TyCtxt};
+use crate::mir::{interpret, pretty_print_const_value, Promoted};
+use crate::ty::{self, print::pretty_print_const, List, Ty, TyCtxt};
 use crate::ty::{GenericArgs, GenericArgsRef};
 use crate::ty::{ScalarInt, UserTypeAnnotationIndex};
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 3a79e1d31b4..fb6dbe34a89 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -6,7 +6,7 @@ use crate::mir::interpret::{AllocRange, ErrorHandled, ConstAllocation, ConstValu
 use crate::mir::visit::MirVisitable;
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
-use crate::ty::print::with_no_trimmed_paths;
+use crate::ty::print::{pretty_print_const, with_no_trimmed_paths};
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, List, Ty, TyCtxt};
@@ -20,7 +20,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_hir::{self, GeneratorKind, ImplicitSelfKind};
 use rustc_hir::{self as hir, HirId};
 use rustc_session::Session;
-use rustc_target::abi::{FieldIdx, Size, VariantIdx};
+use rustc_target::abi::{FieldIdx, VariantIdx};
 
 use polonius_engine::Atom;
 pub use rustc_ast::Mutability;
@@ -46,7 +46,6 @@ pub use basic_blocks::BasicBlocks;
 
 mod basic_blocks;
 mod consts;
-pub use consts::*;
 pub mod coverage;
 mod generic_graph;
 pub mod generic_graphviz;
@@ -58,10 +57,8 @@ pub mod pretty;
 mod query;
 pub mod spanview;
 mod syntax;
-pub use syntax::*;
 pub mod tcx;
 mod terminator;
-pub use terminator::*;
 
 pub mod traversal;
 mod type_foldable;
@@ -72,6 +69,10 @@ pub use self::graphviz::write_mir_graphviz;
 pub use self::pretty::{
     create_dump_file, display_allocation, dump_enabled, dump_mir, write_mir_pretty, PassWhere,
 };
+pub use consts::*;
+pub use pretty::pretty_print_const_value;
+pub use syntax::*;
+pub use terminator::*;
 
 /// Types for locals
 pub type LocalDecls<'tcx> = IndexSlice<Local, LocalDecl<'tcx>>;
@@ -2459,176 +2460,6 @@ rustc_index::newtype_index! {
     pub struct Promoted {}
 }
 
-fn pretty_print_const<'tcx>(
-    c: ty::Const<'tcx>,
-    fmt: &mut Formatter<'_>,
-    print_types: bool,
-) -> fmt::Result {
-    use crate::ty::print::PrettyPrinter;
-    ty::tls::with(|tcx| {
-        let literal = tcx.lift(c).unwrap();
-        let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-        cx.print_alloc_ids = true;
-        let cx = cx.pretty_print_const(literal, print_types)?;
-        fmt.write_str(&cx.into_buffer())?;
-        Ok(())
-    })
-}
-
-fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result {
-    write!(fmt, "b\"{}\"", byte_str.escape_ascii())
-}
-
-fn comma_sep<'tcx>(
-    fmt: &mut Formatter<'_>,
-    elems: Vec<(ConstValue<'tcx>, Ty<'tcx>)>,
-) -> fmt::Result {
-    let mut first = true;
-    for (ct, ty) in elems {
-        if !first {
-            fmt.write_str(", ")?;
-        }
-        pretty_print_const_value(ct, ty, fmt)?;
-        first = false;
-    }
-    Ok(())
-}
-
-// FIXME: Move that into `mir/pretty.rs`.
-fn pretty_print_const_value<'tcx>(
-    ct: ConstValue<'tcx>,
-    ty: Ty<'tcx>,
-    fmt: &mut Formatter<'_>,
-) -> fmt::Result {
-    use crate::ty::print::PrettyPrinter;
-
-    ty::tls::with(|tcx| {
-        let ct = tcx.lift(ct).unwrap();
-        let ty = tcx.lift(ty).unwrap();
-
-        if tcx.sess.verbose() {
-            fmt.write_str(&format!("ConstValue({ct:?}: {ty})"))?;
-            return Ok(());
-        }
-
-        let u8_type = tcx.types.u8;
-        match (ct, ty.kind()) {
-            // Byte/string slices, printed as (byte) string literals.
-            (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {
-                if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
-                    fmt.write_str(&format!("{:?}", String::from_utf8_lossy(data)))?;
-                    return Ok(());
-                }
-            }
-            (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(t) if *t == u8_type) => {
-                if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
-                    pretty_print_byte_str(fmt, data)?;
-                    return Ok(());
-                }
-            }
-            (ConstValue::Indirect { alloc_id, offset }, ty::Array(t, n)) if *t == u8_type => {
-                let n = n.try_to_target_usize(tcx).unwrap();
-                let alloc = tcx.global_alloc(alloc_id).unwrap_memory();
-                // cast is ok because we already checked for pointer size (32 or 64 bit) above
-                let range = AllocRange { start: offset, size: Size::from_bytes(n) };
-                let byte_str = alloc.inner().get_bytes_strip_provenance(&tcx, range).unwrap();
-                fmt.write_str("*")?;
-                pretty_print_byte_str(fmt, byte_str)?;
-                return Ok(());
-            }
-            // Aggregates, printed as array/tuple/struct/variant construction syntax.
-            //
-            // NB: the `has_non_region_param` check ensures that we can use
-            // the `destructure_const` query with an empty `ty::ParamEnv` without
-            // introducing ICEs (e.g. via `layout_of`) from missing bounds.
-            // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
-            // to be able to destructure the tuple into `(0u8, *mut T)`
-            (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => {
-                let ct = tcx.lift(ct).unwrap();
-                let ty = tcx.lift(ty).unwrap();
-                if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics((ct, ty)) {
-                    let fields: Vec<(ConstValue<'_>, Ty<'_>)> = contents.fields.to_vec();
-                    match *ty.kind() {
-                        ty::Array(..) => {
-                            fmt.write_str("[")?;
-                            comma_sep(fmt, fields)?;
-                            fmt.write_str("]")?;
-                        }
-                        ty::Tuple(..) => {
-                            fmt.write_str("(")?;
-                            comma_sep(fmt, fields)?;
-                            if contents.fields.len() == 1 {
-                                fmt.write_str(",")?;
-                            }
-                            fmt.write_str(")")?;
-                        }
-                        ty::Adt(def, _) if def.variants().is_empty() => {
-                            fmt.write_str(&format!("{{unreachable(): {ty}}}"))?;
-                        }
-                        ty::Adt(def, args) => {
-                            let variant_idx = contents
-                                .variant
-                                .expect("destructed mir constant of adt without variant idx");
-                            let variant_def = &def.variant(variant_idx);
-                            let args = tcx.lift(args).unwrap();
-                            let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                            cx.print_alloc_ids = true;
-                            let cx = cx.print_value_path(variant_def.def_id, args)?;
-                            fmt.write_str(&cx.into_buffer())?;
-
-                            match variant_def.ctor_kind() {
-                                Some(CtorKind::Const) => {}
-                                Some(CtorKind::Fn) => {
-                                    fmt.write_str("(")?;
-                                    comma_sep(fmt, fields)?;
-                                    fmt.write_str(")")?;
-                                }
-                                None => {
-                                    fmt.write_str(" {{ ")?;
-                                    let mut first = true;
-                                    for (field_def, (ct, ty)) in
-                                        iter::zip(&variant_def.fields, fields)
-                                    {
-                                        if !first {
-                                            fmt.write_str(", ")?;
-                                        }
-                                        write!(fmt, "{}: ", field_def.name)?;
-                                        pretty_print_const_value(ct, ty, fmt)?;
-                                        first = false;
-                                    }
-                                    fmt.write_str(" }}")?;
-                                }
-                            }
-                        }
-                        _ => unreachable!(),
-                    }
-                    return Ok(());
-                }
-            }
-            (ConstValue::Scalar(scalar), _) => {
-                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                cx.print_alloc_ids = true;
-                let ty = tcx.lift(ty).unwrap();
-                cx = cx.pretty_print_const_scalar(scalar, ty)?;
-                fmt.write_str(&cx.into_buffer())?;
-                return Ok(());
-            }
-            (ConstValue::ZeroSized, ty::FnDef(d, s)) => {
-                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                cx.print_alloc_ids = true;
-                let cx = cx.print_value_path(*d, s)?;
-                fmt.write_str(&cx.into_buffer())?;
-                return Ok(());
-            }
-            // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
-            // their fields instead of just dumping the memory.
-            _ => {}
-        }
-        // Fall back to debug pretty printing for invalid constants.
-        write!(fmt, "{ct:?}: {ty}")
-    })
-}
-
 /// `Location` represents the position of the start of the statement; or, if
 /// `statement_index` equals the number of statements, then the start of the
 /// terminator.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index c4fae27a7a5..56b59fe5204 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1085,6 +1085,159 @@ pub fn dump_mir_def_ids(tcx: TyCtxt<'_>, single: Option<DefId>) -> Vec<DefId> {
     }
 }
 
+fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result {
+    write!(fmt, "b\"{}\"", byte_str.escape_ascii())
+}
+
+fn comma_sep<'tcx>(
+    fmt: &mut Formatter<'_>,
+    elems: Vec<(ConstValue<'tcx>, Ty<'tcx>)>,
+) -> fmt::Result {
+    let mut first = true;
+    for (ct, ty) in elems {
+        if !first {
+            fmt.write_str(", ")?;
+        }
+        pretty_print_const_value(ct, ty, fmt)?;
+        first = false;
+    }
+    Ok(())
+}
+
+pub fn pretty_print_const_value<'tcx>(
+    ct: ConstValue<'tcx>,
+    ty: Ty<'tcx>,
+    fmt: &mut Formatter<'_>,
+) -> fmt::Result {
+    use crate::ty::print::PrettyPrinter;
+
+    ty::tls::with(|tcx| {
+        let ct = tcx.lift(ct).unwrap();
+        let ty = tcx.lift(ty).unwrap();
+
+        if tcx.sess.verbose() {
+            fmt.write_str(&format!("ConstValue({ct:?}: {ty})"))?;
+            return Ok(());
+        }
+
+        let u8_type = tcx.types.u8;
+        match (ct, ty.kind()) {
+            // Byte/string slices, printed as (byte) string literals.
+            (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {
+                if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
+                    fmt.write_str(&format!("{:?}", String::from_utf8_lossy(data)))?;
+                    return Ok(());
+                }
+            }
+            (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(t) if *t == u8_type) => {
+                if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
+                    pretty_print_byte_str(fmt, data)?;
+                    return Ok(());
+                }
+            }
+            (ConstValue::Indirect { alloc_id, offset }, ty::Array(t, n)) if *t == u8_type => {
+                let n = n.try_to_target_usize(tcx).unwrap();
+                let alloc = tcx.global_alloc(alloc_id).unwrap_memory();
+                // cast is ok because we already checked for pointer size (32 or 64 bit) above
+                let range = AllocRange { start: offset, size: Size::from_bytes(n) };
+                let byte_str = alloc.inner().get_bytes_strip_provenance(&tcx, range).unwrap();
+                fmt.write_str("*")?;
+                pretty_print_byte_str(fmt, byte_str)?;
+                return Ok(());
+            }
+            // Aggregates, printed as array/tuple/struct/variant construction syntax.
+            //
+            // NB: the `has_non_region_param` check ensures that we can use
+            // the `destructure_const` query with an empty `ty::ParamEnv` without
+            // introducing ICEs (e.g. via `layout_of`) from missing bounds.
+            // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
+            // to be able to destructure the tuple into `(0u8, *mut T)`
+            (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => {
+                let ct = tcx.lift(ct).unwrap();
+                let ty = tcx.lift(ty).unwrap();
+                if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics((ct, ty)) {
+                    let fields: Vec<(ConstValue<'_>, Ty<'_>)> = contents.fields.to_vec();
+                    match *ty.kind() {
+                        ty::Array(..) => {
+                            fmt.write_str("[")?;
+                            comma_sep(fmt, fields)?;
+                            fmt.write_str("]")?;
+                        }
+                        ty::Tuple(..) => {
+                            fmt.write_str("(")?;
+                            comma_sep(fmt, fields)?;
+                            if contents.fields.len() == 1 {
+                                fmt.write_str(",")?;
+                            }
+                            fmt.write_str(")")?;
+                        }
+                        ty::Adt(def, _) if def.variants().is_empty() => {
+                            fmt.write_str(&format!("{{unreachable(): {ty}}}"))?;
+                        }
+                        ty::Adt(def, args) => {
+                            let variant_idx = contents
+                                .variant
+                                .expect("destructed mir constant of adt without variant idx");
+                            let variant_def = &def.variant(variant_idx);
+                            let args = tcx.lift(args).unwrap();
+                            let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
+                            cx.print_alloc_ids = true;
+                            let cx = cx.print_value_path(variant_def.def_id, args)?;
+                            fmt.write_str(&cx.into_buffer())?;
+
+                            match variant_def.ctor_kind() {
+                                Some(CtorKind::Const) => {}
+                                Some(CtorKind::Fn) => {
+                                    fmt.write_str("(")?;
+                                    comma_sep(fmt, fields)?;
+                                    fmt.write_str(")")?;
+                                }
+                                None => {
+                                    fmt.write_str(" {{ ")?;
+                                    let mut first = true;
+                                    for (field_def, (ct, ty)) in
+                                        iter::zip(&variant_def.fields, fields)
+                                    {
+                                        if !first {
+                                            fmt.write_str(", ")?;
+                                        }
+                                        write!(fmt, "{}: ", field_def.name)?;
+                                        pretty_print_const_value(ct, ty, fmt)?;
+                                        first = false;
+                                    }
+                                    fmt.write_str(" }}")?;
+                                }
+                            }
+                        }
+                        _ => unreachable!(),
+                    }
+                    return Ok(());
+                }
+            }
+            (ConstValue::Scalar(scalar), _) => {
+                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
+                cx.print_alloc_ids = true;
+                let ty = tcx.lift(ty).unwrap();
+                cx = cx.pretty_print_const_scalar(scalar, ty)?;
+                fmt.write_str(&cx.into_buffer())?;
+                return Ok(());
+            }
+            (ConstValue::ZeroSized, ty::FnDef(d, s)) => {
+                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
+                cx.print_alloc_ids = true;
+                let cx = cx.print_value_path(*d, s)?;
+                fmt.write_str(&cx.into_buffer())?;
+                return Ok(());
+            }
+            // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
+            // their fields instead of just dumping the memory.
+            _ => {}
+        }
+        // Fall back to debug pretty printing for invalid constants.
+        write!(fmt, "{ct:?}: {ty}")
+    })
+}
+
 /// Calc converted u64 decimal into hex and return it's length in chars
 ///
 /// ```ignore (cannot-test-private-function)
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index e1d4e43841d..d958e25e629 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1713,6 +1713,21 @@ pub trait PrettyPrinter<'tcx>:
     }
 }
 
+pub fn pretty_print_const<'tcx>(
+    c: ty::Const<'tcx>,
+    fmt: &mut fmt::Formatter<'_>,
+    print_types: bool,
+) -> fmt::Result {
+    ty::tls::with(|tcx| {
+        let literal = tcx.lift(c).unwrap();
+        let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
+        cx.print_alloc_ids = true;
+        let cx = cx.pretty_print_const(literal, print_types)?;
+        fmt.write_str(&cx.into_buffer())?;
+        Ok(())
+    })
+}
+
 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
 pub struct FmtPrinter<'a, 'tcx>(Box<FmtPrinterData<'a, 'tcx>>);