about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2020-04-17 03:55:39 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2020-04-17 05:18:32 +0300
commiteccb28e3d67460f77331eb5ecceab36181831946 (patch)
tree0be938445b6fb8cc8f28ae44a81dd9c1f3554eb8
parentaabed9322e78b280d54fe7a90bb088932731d967 (diff)
downloadrust-eccb28e3d67460f77331eb5ecceab36181831946.tar.gz
rust-eccb28e3d67460f77331eb5ecceab36181831946.zip
ty/print: pretty-print constant aggregates (arrays, tuples and ADTs).
-rw-r--r--src/librustc_middle/query/mod.rs2
-rw-r--r--src/librustc_middle/ty/print/pretty.rs79
-rw-r--r--src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff2
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff2
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff8
7 files changed, 72 insertions, 25 deletions
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index 3ddb290fc8d..1b94966c347 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -574,7 +574,7 @@ rustc_queries! {
             desc { "extract field of const" }
         }
 
-        /// Destructure a constant ADT or array into its variant indent and its
+        /// Destructure a constant ADT or array into its variant index and its
         /// field values.
         query destructure_const(
             key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index 0cabd201a95..85c05515bd7 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -9,7 +9,7 @@ use rustc_apfloat::Float;
 use rustc_ast::ast;
 use rustc_attr::{SignedInt, UnsignedInt};
 use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Namespace};
+use rustc_hir::def::{CtorKind, DefKind, Namespace};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_span::symbol::{kw, Symbol};
@@ -1037,19 +1037,6 @@ pub trait PrettyPrinter<'tcx>:
             }
             // For function type zsts just printing the path is enough
             (Scalar::Raw { size: 0, .. }, ty::FnDef(d, s)) => p!(print_value_path(*d, s)),
-            // Empty tuples are frequently occurring, so don't print the fallback.
-            (Scalar::Raw { size: 0, .. }, ty::Tuple(ts)) if ts.is_empty() => p!(write("()")),
-            // Zero element arrays have a trivial representation.
-            (
-                Scalar::Raw { size: 0, .. },
-                ty::Array(
-                    _,
-                    ty::Const {
-                        val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data: 0, .. })),
-                        ..
-                    },
-                ),
-            ) => p!(write("[]")),
             // Nontrivial types with scalar bit representation
             (Scalar::Raw { data, size }, _) => {
                 let print = |mut this: Self| {
@@ -1118,14 +1105,14 @@ pub trait PrettyPrinter<'tcx>:
         define_scoped_cx!(self);
 
         if self.tcx().sess.verbose() {
-            p!(write("ConstValue({:?}: {:?})", ct, ty));
+            p!(write("ConstValue({:?}: ", ct), print(ty), write(")"));
             return Ok(self);
         }
 
         let u8_type = self.tcx().types.u8;
 
         match (ct, &ty.kind) {
-            (ConstValue::Scalar(scalar), _) => self.pretty_print_const_scalar(scalar, ty, print_ty),
+            // Byte/string slices, printed as (byte) string literals.
             (
                 ConstValue::Slice { data, start, end },
                 ty::Ref(_, ty::TyS { kind: ty::Slice(t), .. }, _),
@@ -1159,6 +1146,66 @@ pub trait PrettyPrinter<'tcx>:
                 p!(pretty_print_byte_str(byte_str));
                 Ok(self)
             }
+
+            // Aggregates, printed as array/tuple/struct/variant construction syntax.
+            //
+            // NB: the `has_param_types_or_consts` 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)
+            //
+            // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
+            // correct `ty::ParamEnv` to allow printing *all* constant values.
+            (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
+                let contents = self.tcx().destructure_const(
+                    ty::ParamEnv::reveal_all()
+                        .and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })),
+                );
+                let fields = contents.fields.iter().copied();
+
+                match ty.kind {
+                    ty::Array(..) => {
+                        p!(write("["), comma_sep(fields), write("]"));
+                    }
+                    ty::Tuple(..) => {
+                        p!(write("("), comma_sep(fields));
+                        if contents.fields.len() == 1 {
+                            p!(write(","));
+                        }
+                        p!(write(")"));
+                    }
+                    ty::Adt(def, substs) => {
+                        let variant_def = &def.variants[contents.variant];
+                        p!(print_value_path(variant_def.def_id, substs));
+
+                        match variant_def.ctor_kind {
+                            CtorKind::Const => {}
+                            CtorKind::Fn => {
+                                p!(write("("), comma_sep(fields), write(")"));
+                            }
+                            CtorKind::Fictive => {
+                                p!(write(" {{ "));
+                                let mut first = true;
+                                for (field_def, field) in variant_def.fields.iter().zip(fields) {
+                                    if !first {
+                                        p!(write(", "));
+                                    }
+                                    p!(write("{}: ", field_def.ident), print(field));
+                                    first = false;
+                                }
+                                p!(write(" }}"));
+                            }
+                        }
+                    }
+                    _ => unreachable!(),
+                }
+
+                Ok(self)
+            }
+
+            (ConstValue::Scalar(scalar), _) => self.pretty_print_const_scalar(scalar, ty, print_ty),
+
             // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
             // their fields instead of just dumping the memory.
             _ => {
diff --git a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff
index d5566b9d761..753c64d6c32 100644
--- a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff
@@ -16,7 +16,7 @@
           StorageLive(_2);                 // bb0[1]: scope 0 at $DIR/discriminant.rs:6:13: 6:64
           StorageLive(_3);                 // bb0[2]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
 -         _3 = std::option::Option::<bool>::Some(const true); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
-+         _3 = const {transmute(0x01): std::option::Option<bool>}; // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
++         _3 = const std::option::Option::<bool>::Some(true); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
                                            // ty::Const
 -                                          // + ty: bool
 +                                          // + ty: std::option::Option<bool>
diff --git a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff
index bdd9c020c95..1d8e945f87a 100644
--- a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff
@@ -16,7 +16,7 @@
           StorageLive(_2);                 // bb0[1]: scope 0 at $DIR/discriminant.rs:6:13: 6:64
           StorageLive(_3);                 // bb0[2]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
 -         _3 = std::option::Option::<bool>::Some(const true); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
-+         _3 = const {transmute(0x01): std::option::Option<bool>}; // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
++         _3 = const std::option::Option::<bool>::Some(true); // bb0[3]: scope 0 at $DIR/discriminant.rs:6:34: 6:44
                                            // ty::Const
 -                                          // + ty: bool
 +                                          // + ty: std::option::Option<bool>
diff --git a/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff
index 6983e94ff8d..7f2f7cdb176 100644
--- a/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff
@@ -19,7 +19,7 @@
           _2 = Box(std::vec::Vec<u32>);    // bb0[2]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
 -         (*_2) = const std::vec::Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
 +         _4 = &mut (*_2);                 // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }: alloc::raw_vec::RawVec::<u32>; // bb0[4]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
++         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: std::ptr::Unique::<u32> { pointer: {0x4 as *const u32}, _marker: std::marker::PhantomData::<u32> }, cap: 0usize, alloc: std::alloc::Global }; // bb0[4]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
                                            // ty::Const
 -                                          // + ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}
 -                                          // + val: Value(Scalar(<ZST>))
diff --git a/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff
index 38ab9ce9926..b968b33ac52 100644
--- a/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff
@@ -19,7 +19,7 @@
           _2 = Box(std::vec::Vec<u32>);    // bb0[2]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
 -         (*_2) = const std::vec::Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
 +         _4 = &mut (*_2);                 // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }: alloc::raw_vec::RawVec::<u32>; // bb0[4]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
++         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: std::ptr::Unique::<u32> { pointer: {0x4 as *const u32}, _marker: std::marker::PhantomData::<u32> }, cap: 0usize, alloc: std::alloc::Global }; // bb0[4]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
                                            // ty::Const
 -                                          // + ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}
 -                                          // + val: Value(Scalar(<ZST>))
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff
index 8613a812a83..855ead7ea05 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff
@@ -24,7 +24,7 @@
 -         StorageLive(_2);                 // bb0[1]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:13:21: 13:23
 -         _2 = const ();                   // bb0[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:13:21: 13:23
 +         StorageLive(_1);                 // bb0[0]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
-+         _1 = const use_zst(const {transmute(()): ((), ())}) -> bb1; // bb0[1]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
++         _1 = const use_zst(const ((), ())) -> bb1; // bb0[1]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
                                            // ty::Const
 -                                          // + ty: ()
 -                                          // + val: Value(Scalar(<ZST>))
@@ -39,7 +39,7 @@
 -                                          // mir::Constant
 -                                          // + span: $DIR/simplify-locals-removes-unused-consts.rs:13:25: 13:27
 -                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
--         _1 = const {transmute(()): ((), ())}; // bb0[5]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:13:20: 13:28
+-         _1 = const ((), ());             // bb0[5]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:13:20: 13:28
 -                                          // ty::Const
 -                                          // + ty: ((), ())
 -                                          // + val: Value(Scalar(<ZST>))
@@ -68,7 +68,7 @@
 -                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         StorageDead(_7);                 // bb0[14]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:20: 14:21
 -         StorageDead(_6);                 // bb0[15]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:20: 14:21
--         _4 = const use_zst(const {transmute(()): ((), ())}) -> bb1; // bb0[16]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
+-         _4 = const use_zst(const ((), ())) -> bb1; // bb0[16]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
 -                                          // ty::Const
                                            // + ty: fn(((), ())) {use_zst}
                                            // + val: Value(Scalar(<ZST>))
@@ -88,7 +88,7 @@
 -         StorageLive(_8);                 // bb1[1]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
 -         StorageLive(_10);                // bb1[2]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:30
 -         StorageLive(_11);                // bb1[3]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
--         _11 = const {transmute(0x28): Temp}; // bb1[4]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
+-         _11 = const Temp { x: 40u8 };    // bb1[4]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
 +         StorageDead(_1);                 // bb1[0]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:22: 14:23
 +         StorageLive(_2);                 // bb1[1]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
 +         _2 = const use_u8(const 42u8) -> bb2; // bb1[2]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35