@@ -9,7 +9,7 @@ use rustc_apfloat::Float;
9
9
use rustc_ast:: ast;
10
10
use rustc_attr:: { SignedInt , UnsignedInt } ;
11
11
use rustc_hir as hir;
12
- use rustc_hir:: def:: { DefKind , Namespace } ;
12
+ use rustc_hir:: def:: { CtorKind , DefKind , Namespace } ;
13
13
use rustc_hir:: def_id:: { CrateNum , DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
14
14
use rustc_hir:: definitions:: { DefPathData , DisambiguatedDefPathData } ;
15
15
use rustc_span:: symbol:: { kw, Symbol } ;
@@ -1037,19 +1037,6 @@ pub trait PrettyPrinter<'tcx>:
1037
1037
}
1038
1038
// For function type zsts just printing the path is enough
1039
1039
( Scalar :: Raw { size : 0 , .. } , ty:: FnDef ( d, s) ) => p ! ( print_value_path( * d, s) ) ,
1040
- // Empty tuples are frequently occurring, so don't print the fallback.
1041
- ( Scalar :: Raw { size : 0 , .. } , ty:: Tuple ( ts) ) if ts. is_empty ( ) => p ! ( write( "()" ) ) ,
1042
- // Zero element arrays have a trivial representation.
1043
- (
1044
- Scalar :: Raw { size : 0 , .. } ,
1045
- ty:: Array (
1046
- _,
1047
- ty:: Const {
1048
- val : ty:: ConstKind :: Value ( ConstValue :: Scalar ( Scalar :: Raw { data : 0 , .. } ) ) ,
1049
- ..
1050
- } ,
1051
- ) ,
1052
- ) => p ! ( write( "[]" ) ) ,
1053
1040
// Nontrivial types with scalar bit representation
1054
1041
( Scalar :: Raw { data, size } , _) => {
1055
1042
let print = |mut this : Self | {
@@ -1118,14 +1105,14 @@ pub trait PrettyPrinter<'tcx>:
1118
1105
define_scoped_cx ! ( self ) ;
1119
1106
1120
1107
if self . tcx ( ) . sess . verbose ( ) {
1121
- p ! ( write( "ConstValue({:?}: {:?}) " , ct, ty ) ) ;
1108
+ p ! ( write( "ConstValue({:?}: " , ct) , print ( ty ) , write ( ")" ) ) ;
1122
1109
return Ok ( self ) ;
1123
1110
}
1124
1111
1125
1112
let u8_type = self . tcx ( ) . types . u8 ;
1126
1113
1127
1114
match ( ct, & ty. kind ) {
1128
- ( ConstValue :: Scalar ( scalar ) , _ ) => self . pretty_print_const_scalar ( scalar , ty , print_ty ) ,
1115
+ // Byte/string slices, printed as (byte) string literals.
1129
1116
(
1130
1117
ConstValue :: Slice { data, start, end } ,
1131
1118
ty:: Ref ( _, ty:: TyS { kind : ty:: Slice ( t) , .. } , _) ,
@@ -1159,6 +1146,66 @@ pub trait PrettyPrinter<'tcx>:
1159
1146
p ! ( pretty_print_byte_str( byte_str) ) ;
1160
1147
Ok ( self )
1161
1148
}
1149
+
1150
+ // Aggregates, printed as array/tuple/struct/variant construction syntax.
1151
+ //
1152
+ // NB: the `has_param_types_or_consts` check ensures that we can use
1153
+ // the `destructure_const` query with an empty `ty::ParamEnv` without
1154
+ // introducing ICEs (e.g. via `layout_of`) from missing bounds.
1155
+ // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
1156
+ // to be able to destructure the tuple into `(0u8, *mut T)
1157
+ //
1158
+ // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
1159
+ // correct `ty::ParamEnv` to allow printing *all* constant values.
1160
+ ( _, ty:: Array ( ..) | ty:: Tuple ( ..) | ty:: Adt ( ..) ) if !ty. has_param_types_or_consts ( ) => {
1161
+ let contents = self . tcx ( ) . destructure_const (
1162
+ ty:: ParamEnv :: reveal_all ( )
1163
+ . and ( self . tcx ( ) . mk_const ( ty:: Const { val : ty:: ConstKind :: Value ( ct) , ty } ) ) ,
1164
+ ) ;
1165
+ let fields = contents. fields . iter ( ) . copied ( ) ;
1166
+
1167
+ match ty. kind {
1168
+ ty:: Array ( ..) => {
1169
+ p ! ( write( "[" ) , comma_sep( fields) , write( "]" ) ) ;
1170
+ }
1171
+ ty:: Tuple ( ..) => {
1172
+ p ! ( write( "(" ) , comma_sep( fields) ) ;
1173
+ if contents. fields . len ( ) == 1 {
1174
+ p ! ( write( "," ) ) ;
1175
+ }
1176
+ p ! ( write( ")" ) ) ;
1177
+ }
1178
+ ty:: Adt ( def, substs) => {
1179
+ let variant_def = & def. variants [ contents. variant ] ;
1180
+ p ! ( print_value_path( variant_def. def_id, substs) ) ;
1181
+
1182
+ match variant_def. ctor_kind {
1183
+ CtorKind :: Const => { }
1184
+ CtorKind :: Fn => {
1185
+ p ! ( write( "(" ) , comma_sep( fields) , write( ")" ) ) ;
1186
+ }
1187
+ CtorKind :: Fictive => {
1188
+ p ! ( write( " {{ " ) ) ;
1189
+ let mut first = true ;
1190
+ for ( field_def, field) in variant_def. fields . iter ( ) . zip ( fields) {
1191
+ if !first {
1192
+ p ! ( write( ", " ) ) ;
1193
+ }
1194
+ p ! ( write( "{}: " , field_def. ident) , print( field) ) ;
1195
+ first = false ;
1196
+ }
1197
+ p ! ( write( " }}" ) ) ;
1198
+ }
1199
+ }
1200
+ }
1201
+ _ => unreachable ! ( ) ,
1202
+ }
1203
+
1204
+ Ok ( self )
1205
+ }
1206
+
1207
+ ( ConstValue :: Scalar ( scalar) , _) => self . pretty_print_const_scalar ( scalar, ty, print_ty) ,
1208
+
1162
1209
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
1163
1210
// their fields instead of just dumping the memory.
1164
1211
_ => {
0 commit comments