@@ -455,26 +455,27 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
455455 self . push ( & format ! ( "+ user_ty: {user_ty:?}" ) ) ;
456456 }
457457
458- // FIXME: this is a poor version of `pretty_print_const_value`.
459- let fmt_val = |val : & ConstValue < ' tcx > | match val {
460- ConstValue :: ZeroSized => "<ZST>" . to_string ( ) ,
461- ConstValue :: Scalar ( s) => format ! ( "Scalar({s:?})" ) ,
462- ConstValue :: Slice { .. } => "Slice(..)" . to_string ( ) ,
463- ConstValue :: Indirect { .. } => "ByRef(..)" . to_string ( ) ,
458+ let fmt_val = |val : ConstValue < ' tcx > , ty : Ty < ' tcx > | {
459+ let tcx = self . tcx ;
460+ rustc_data_structures:: make_display ( move |fmt| {
461+ pretty_print_const_value_tcx ( tcx, val, ty, fmt)
462+ } )
464463 } ;
465464
465+ // FIXME: call pretty_print_const_valtree?
466466 let fmt_valtree = |valtree : & ty:: ValTree < ' tcx > | match valtree {
467- ty:: ValTree :: Leaf ( leaf) => format ! ( "ValTree:: Leaf({leaf:?})" ) ,
468- ty:: ValTree :: Branch ( _) => "ValTree:: Branch(..)" . to_string ( ) ,
467+ ty:: ValTree :: Leaf ( leaf) => format ! ( "Leaf({leaf:?})" ) ,
468+ ty:: ValTree :: Branch ( _) => "Branch(..)" . to_string ( ) ,
469469 } ;
470470
471471 let val = match literal {
472472 ConstantKind :: Ty ( ct) => match ct. kind ( ) {
473- ty:: ConstKind :: Param ( p) => format ! ( "Param({p})" ) ,
473+ ty:: ConstKind :: Param ( p) => format ! ( "ty:: Param({p})" ) ,
474474 ty:: ConstKind :: Unevaluated ( uv) => {
475- format ! ( "Unevaluated({}, {:?})" , self . tcx. def_path_str( uv. def) , uv. args, )
475+ format ! ( "ty:: Unevaluated({}, {:?})" , self . tcx. def_path_str( uv. def) , uv. args, )
476476 }
477- ty:: ConstKind :: Value ( val) => format ! ( "Value({})" , fmt_valtree( & val) ) ,
477+ ty:: ConstKind :: Value ( val) => format ! ( "ty::Valtree({})" , fmt_valtree( & val) ) ,
478+ // No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
478479 ty:: ConstKind :: Error ( _) => "Error" . to_string ( ) ,
479480 // These variants shouldn't exist in the MIR.
480481 ty:: ConstKind :: Placeholder ( _)
@@ -490,10 +491,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
490491 uv. promoted,
491492 )
492493 }
493- // To keep the diffs small, we render this like we render `ty::Const::Value`.
494- //
495- // This changes once `ty::Const::Value` is represented using valtrees.
496- ConstantKind :: Val ( val, _) => format ! ( "Value({})" , fmt_val( & val) ) ,
494+ ConstantKind :: Val ( val, ty) => format ! ( "Value({})" , fmt_val( * val, * ty) ) ,
497495 } ;
498496
499497 // This reflects what `Const` looked liked before `val` was renamed
@@ -1090,6 +1088,7 @@ fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Resul
10901088}
10911089
10921090fn comma_sep < ' tcx > (
1091+ tcx : TyCtxt < ' tcx > ,
10931092 fmt : & mut Formatter < ' _ > ,
10941093 elems : Vec < ( ConstValue < ' tcx > , Ty < ' tcx > ) > ,
10951094) -> fmt:: Result {
@@ -1098,143 +1097,150 @@ fn comma_sep<'tcx>(
10981097 if !first {
10991098 fmt. write_str ( ", " ) ?;
11001099 }
1101- pretty_print_const_value ( ct, ty, fmt) ?;
1100+ pretty_print_const_value_tcx ( tcx , ct, ty, fmt) ?;
11021101 first = false ;
11031102 }
11041103 Ok ( ( ) )
11051104}
11061105
1107- pub fn pretty_print_const_value < ' tcx > (
1106+ fn pretty_print_const_value_tcx < ' tcx > (
1107+ tcx : TyCtxt < ' tcx > ,
11081108 ct : ConstValue < ' tcx > ,
11091109 ty : Ty < ' tcx > ,
11101110 fmt : & mut Formatter < ' _ > ,
11111111) -> fmt:: Result {
11121112 use crate :: ty:: print:: PrettyPrinter ;
11131113
1114- ty:: tls:: with ( |tcx| {
1115- let ct = tcx. lift ( ct) . unwrap ( ) ;
1116- let ty = tcx. lift ( ty) . unwrap ( ) ;
1117-
1118- if tcx. sess . verbose ( ) {
1119- fmt. write_str ( & format ! ( "ConstValue({ct:?}: {ty})" ) ) ?;
1120- return Ok ( ( ) ) ;
1121- }
1114+ if tcx. sess . verbose ( ) {
1115+ fmt. write_str ( & format ! ( "ConstValue({ct:?}: {ty})" ) ) ?;
1116+ return Ok ( ( ) ) ;
1117+ }
11221118
1123- let u8_type = tcx. types . u8 ;
1124- match ( ct, ty. kind ( ) ) {
1125- // Byte/string slices, printed as (byte) string literals.
1126- ( _, ty:: Ref ( _, inner_ty, _) ) if matches ! ( inner_ty. kind( ) , ty:: Str ) => {
1127- if let Some ( data) = ct. try_get_slice_bytes_for_diagnostics ( tcx) {
1128- fmt. write_str ( & format ! ( "{:?}" , String :: from_utf8_lossy( data) ) ) ?;
1129- return Ok ( ( ) ) ;
1130- }
1131- }
1132- ( _, ty:: Ref ( _, inner_ty, _) ) if matches ! ( inner_ty. kind( ) , ty:: Slice ( t) if * t == u8_type) => {
1133- if let Some ( data) = ct. try_get_slice_bytes_for_diagnostics ( tcx) {
1134- pretty_print_byte_str ( fmt, data) ?;
1135- return Ok ( ( ) ) ;
1136- }
1119+ let u8_type = tcx. types . u8 ;
1120+ match ( ct, ty. kind ( ) ) {
1121+ // Byte/string slices, printed as (byte) string literals.
1122+ ( _, ty:: Ref ( _, inner_ty, _) ) if matches ! ( inner_ty. kind( ) , ty:: Str ) => {
1123+ if let Some ( data) = ct. try_get_slice_bytes_for_diagnostics ( tcx) {
1124+ fmt. write_str ( & format ! ( "{:?}" , String :: from_utf8_lossy( data) ) ) ?;
1125+ return Ok ( ( ) ) ;
11371126 }
1138- ( ConstValue :: Indirect { alloc_id, offset } , ty:: Array ( t, n) ) if * t == u8_type => {
1139- let n = n. try_to_target_usize ( tcx) . unwrap ( ) ;
1140- let alloc = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
1141- // cast is ok because we already checked for pointer size (32 or 64 bit) above
1142- let range = AllocRange { start : offset, size : Size :: from_bytes ( n) } ;
1143- let byte_str = alloc. inner ( ) . get_bytes_strip_provenance ( & tcx, range) . unwrap ( ) ;
1144- fmt. write_str ( "*" ) ?;
1145- pretty_print_byte_str ( fmt, byte_str) ?;
1127+ }
1128+ ( _, ty:: Ref ( _, inner_ty, _) ) if matches ! ( inner_ty. kind( ) , ty:: Slice ( t) if * t == u8_type) => {
1129+ if let Some ( data) = ct. try_get_slice_bytes_for_diagnostics ( tcx) {
1130+ pretty_print_byte_str ( fmt, data) ?;
11461131 return Ok ( ( ) ) ;
11471132 }
1148- // Aggregates, printed as array/tuple/struct/variant construction syntax.
1149- //
1150- // NB: the `has_non_region_param` check ensures that we can use
1151- // the `destructure_const` query with an empty `ty::ParamEnv` without
1152- // introducing ICEs (e.g. via `layout_of`) from missing bounds.
1153- // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
1154- // to be able to destructure the tuple into `(0u8, *mut T)`
1155- ( _, ty:: Array ( ..) | ty:: Tuple ( ..) | ty:: Adt ( ..) ) if !ty. has_non_region_param ( ) => {
1156- let ct = tcx. lift ( ct) . unwrap ( ) ;
1157- let ty = tcx. lift ( ty) . unwrap ( ) ;
1158- if let Some ( contents) = tcx. try_destructure_mir_constant_for_diagnostics ( ( ct, ty) ) {
1159- let fields: Vec < ( ConstValue < ' _ > , Ty < ' _ > ) > = contents. fields . to_vec ( ) ;
1160- match * ty. kind ( ) {
1161- ty:: Array ( ..) => {
1162- fmt. write_str ( "[" ) ?;
1163- comma_sep ( fmt, fields) ?;
1164- fmt. write_str ( "]" ) ?;
1133+ }
1134+ ( ConstValue :: Indirect { alloc_id, offset } , ty:: Array ( t, n) ) if * t == u8_type => {
1135+ let n = n. try_to_target_usize ( tcx) . unwrap ( ) ;
1136+ let alloc = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
1137+ // cast is ok because we already checked for pointer size (32 or 64 bit) above
1138+ let range = AllocRange { start : offset, size : Size :: from_bytes ( n) } ;
1139+ let byte_str = alloc. inner ( ) . get_bytes_strip_provenance ( & tcx, range) . unwrap ( ) ;
1140+ fmt. write_str ( "*" ) ?;
1141+ pretty_print_byte_str ( fmt, byte_str) ?;
1142+ return Ok ( ( ) ) ;
1143+ }
1144+ // Aggregates, printed as array/tuple/struct/variant construction syntax.
1145+ //
1146+ // NB: the `has_non_region_param` check ensures that we can use
1147+ // the `destructure_const` query with an empty `ty::ParamEnv` without
1148+ // introducing ICEs (e.g. via `layout_of`) from missing bounds.
1149+ // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
1150+ // to be able to destructure the tuple into `(0u8, *mut T)`
1151+ ( _, ty:: Array ( ..) | ty:: Tuple ( ..) | ty:: Adt ( ..) ) if !ty. has_non_region_param ( ) => {
1152+ let ct = tcx. lift ( ct) . unwrap ( ) ;
1153+ let ty = tcx. lift ( ty) . unwrap ( ) ;
1154+ if let Some ( contents) = tcx. try_destructure_mir_constant_for_diagnostics ( ( ct, ty) ) {
1155+ let fields: Vec < ( ConstValue < ' _ > , Ty < ' _ > ) > = contents. fields . to_vec ( ) ;
1156+ match * ty. kind ( ) {
1157+ ty:: Array ( ..) => {
1158+ fmt. write_str ( "[" ) ?;
1159+ comma_sep ( tcx, fmt, fields) ?;
1160+ fmt. write_str ( "]" ) ?;
1161+ }
1162+ ty:: Tuple ( ..) => {
1163+ fmt. write_str ( "(" ) ?;
1164+ comma_sep ( tcx, fmt, fields) ?;
1165+ if contents. fields . len ( ) == 1 {
1166+ fmt. write_str ( "," ) ?;
11651167 }
1166- ty:: Tuple ( ..) => {
1167- fmt. write_str ( "(" ) ?;
1168- comma_sep ( fmt, fields) ?;
1169- if contents. fields . len ( ) == 1 {
1170- fmt. write_str ( "," ) ?;
1168+ fmt. write_str ( ")" ) ?;
1169+ }
1170+ ty:: Adt ( def, _) if def. variants ( ) . is_empty ( ) => {
1171+ fmt. write_str ( & format ! ( "{{unreachable(): {ty}}}" ) ) ?;
1172+ }
1173+ ty:: Adt ( def, args) => {
1174+ let variant_idx = contents
1175+ . variant
1176+ . expect ( "destructed mir constant of adt without variant idx" ) ;
1177+ let variant_def = & def. variant ( variant_idx) ;
1178+ let args = tcx. lift ( args) . unwrap ( ) ;
1179+ let mut cx = FmtPrinter :: new ( tcx, Namespace :: ValueNS ) ;
1180+ cx. print_alloc_ids = true ;
1181+ let cx = cx. print_value_path ( variant_def. def_id , args) ?;
1182+ fmt. write_str ( & cx. into_buffer ( ) ) ?;
1183+
1184+ match variant_def. ctor_kind ( ) {
1185+ Some ( CtorKind :: Const ) => { }
1186+ Some ( CtorKind :: Fn ) => {
1187+ fmt. write_str ( "(" ) ?;
1188+ comma_sep ( tcx, fmt, fields) ?;
1189+ fmt. write_str ( ")" ) ?;
11711190 }
1172- fmt. write_str ( ")" ) ?;
1173- }
1174- ty:: Adt ( def, _) if def. variants ( ) . is_empty ( ) => {
1175- fmt. write_str ( & format ! ( "{{unreachable(): {ty}}}" ) ) ?;
1176- }
1177- ty:: Adt ( def, args) => {
1178- let variant_idx = contents
1179- . variant
1180- . expect ( "destructed mir constant of adt without variant idx" ) ;
1181- let variant_def = & def. variant ( variant_idx) ;
1182- let args = tcx. lift ( args) . unwrap ( ) ;
1183- let mut cx = FmtPrinter :: new ( tcx, Namespace :: ValueNS ) ;
1184- cx. print_alloc_ids = true ;
1185- let cx = cx. print_value_path ( variant_def. def_id , args) ?;
1186- fmt. write_str ( & cx. into_buffer ( ) ) ?;
1187-
1188- match variant_def. ctor_kind ( ) {
1189- Some ( CtorKind :: Const ) => { }
1190- Some ( CtorKind :: Fn ) => {
1191- fmt. write_str ( "(" ) ?;
1192- comma_sep ( fmt, fields) ?;
1193- fmt. write_str ( ")" ) ?;
1194- }
1195- None => {
1196- fmt. write_str ( " {{ " ) ?;
1197- let mut first = true ;
1198- for ( field_def, ( ct, ty) ) in
1199- iter:: zip ( & variant_def. fields , fields)
1200- {
1201- if !first {
1202- fmt. write_str ( ", " ) ?;
1203- }
1204- write ! ( fmt, "{}: " , field_def. name) ?;
1205- pretty_print_const_value ( ct, ty, fmt) ?;
1206- first = false ;
1191+ None => {
1192+ fmt. write_str ( " {{ " ) ?;
1193+ let mut first = true ;
1194+ for ( field_def, ( ct, ty) ) in iter:: zip ( & variant_def. fields , fields)
1195+ {
1196+ if !first {
1197+ fmt. write_str ( ", " ) ?;
12071198 }
1208- fmt. write_str ( " }}" ) ?;
1199+ write ! ( fmt, "{}: " , field_def. name) ?;
1200+ pretty_print_const_value_tcx ( tcx, ct, ty, fmt) ?;
1201+ first = false ;
12091202 }
1203+ fmt. write_str ( " }}" ) ?;
12101204 }
12111205 }
1212- _ => unreachable ! ( ) ,
12131206 }
1214- return Ok ( ( ) ) ;
1207+ _ => unreachable ! ( ) ,
12151208 }
1216- }
1217- ( ConstValue :: Scalar ( scalar) , _) => {
1218- let mut cx = FmtPrinter :: new ( tcx, Namespace :: ValueNS ) ;
1219- cx. print_alloc_ids = true ;
1220- let ty = tcx. lift ( ty) . unwrap ( ) ;
1221- cx = cx. pretty_print_const_scalar ( scalar, ty) ?;
1222- fmt. write_str ( & cx. into_buffer ( ) ) ?;
1223- return Ok ( ( ) ) ;
1224- }
1225- ( ConstValue :: ZeroSized , ty:: FnDef ( d, s) ) => {
1226- let mut cx = FmtPrinter :: new ( tcx, Namespace :: ValueNS ) ;
1227- cx. print_alloc_ids = true ;
1228- let cx = cx. print_value_path ( * d, s) ?;
1229- fmt. write_str ( & cx. into_buffer ( ) ) ?;
12301209 return Ok ( ( ) ) ;
12311210 }
1232- // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
1233- // their fields instead of just dumping the memory.
1234- _ => { }
12351211 }
1236- // Fall back to debug pretty printing for invalid constants.
1237- write ! ( fmt, "{ct:?}: {ty}" )
1212+ ( ConstValue :: Scalar ( scalar) , _) => {
1213+ let mut cx = FmtPrinter :: new ( tcx, Namespace :: ValueNS ) ;
1214+ cx. print_alloc_ids = true ;
1215+ let ty = tcx. lift ( ty) . unwrap ( ) ;
1216+ cx = cx. pretty_print_const_scalar ( scalar, ty) ?;
1217+ fmt. write_str ( & cx. into_buffer ( ) ) ?;
1218+ return Ok ( ( ) ) ;
1219+ }
1220+ ( ConstValue :: ZeroSized , ty:: FnDef ( d, s) ) => {
1221+ let mut cx = FmtPrinter :: new ( tcx, Namespace :: ValueNS ) ;
1222+ cx. print_alloc_ids = true ;
1223+ let cx = cx. print_value_path ( * d, s) ?;
1224+ fmt. write_str ( & cx. into_buffer ( ) ) ?;
1225+ return Ok ( ( ) ) ;
1226+ }
1227+ // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
1228+ // their fields instead of just dumping the memory.
1229+ _ => { }
1230+ }
1231+ // Fall back to debug pretty printing for invalid constants.
1232+ write ! ( fmt, "{ct:?}: {ty}" )
1233+ }
1234+
1235+ pub ( crate ) fn pretty_print_const_value < ' tcx > (
1236+ ct : ConstValue < ' tcx > ,
1237+ ty : Ty < ' tcx > ,
1238+ fmt : & mut Formatter < ' _ > ,
1239+ ) -> fmt:: Result {
1240+ ty:: tls:: with ( |tcx| {
1241+ let ct = tcx. lift ( ct) . unwrap ( ) ;
1242+ let ty = tcx. lift ( ty) . unwrap ( ) ;
1243+ pretty_print_const_value_tcx ( tcx, ct, ty, fmt)
12381244 } )
12391245}
12401246
0 commit comments