ty/print: pretty-print constant aggregates (arrays, tuples and ADTs).
This commit is contained in:
parent
aabed9322e
commit
eccb28e3d6
7 changed files with 72 additions and 25 deletions
|
|
@ -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>>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>))
|
||||
|
|
|
|||
|
|
@ -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>))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue