@@ -173,6 +173,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
173173 Region = Self ,
174174 Type = Self ,
175175 DynExistential = Self ,
176+ Const = Self ,
176177 > +
177178 fmt:: Write
178179{
@@ -665,12 +666,10 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
665666 } ,
666667 ty:: Array ( ty, sz) => {
667668 p ! ( write( "[" ) , print( ty) , write( "; " ) ) ;
668- match sz. val {
669- ConstValue :: Unevaluated ( ..) |
670- ConstValue :: Infer ( ..) => p ! ( write( "_" ) ) ,
671- ConstValue :: Param ( ParamConst { name, .. } ) =>
672- p ! ( write( "{}" , name) ) ,
673- _ => p ! ( write( "{}" , sz. unwrap_usize( self . tcx( ) ) ) ) ,
669+ if let Some ( n) = sz. assert_usize ( self . tcx ( ) ) {
670+ p ! ( write( "{}" , n) ) ;
671+ } else {
672+ p ! ( print( sz) ) ;
674673 }
675674 p ! ( write( "]" ) )
676675 }
@@ -808,6 +807,113 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
808807
809808 Ok ( self )
810809 }
810+
811+ fn pretty_print_const (
812+ mut self ,
813+ ct : & ' tcx ty:: Const < ' tcx > ,
814+ ) -> Result < Self :: Const , Self :: Error > {
815+ define_scoped_cx ! ( self ) ;
816+
817+ let u8 = self . tcx ( ) . types . u8 ;
818+ if let ty:: FnDef ( did, substs) = ct. ty . sty {
819+ p ! ( print_value_path( did, substs) ) ;
820+ return Ok ( self ) ;
821+ }
822+ if let ConstValue :: Unevaluated ( did, substs) = ct. val {
823+ match self . tcx ( ) . describe_def ( did) {
824+ | Some ( Def :: Static ( _) )
825+ | Some ( Def :: Const ( _) )
826+ | Some ( Def :: AssociatedConst ( _) ) => p ! ( print_value_path( did, substs) ) ,
827+ _ => if did. is_local ( ) {
828+ let span = self . tcx ( ) . def_span ( did) ;
829+ if let Ok ( snip) = self . tcx ( ) . sess . source_map ( ) . span_to_snippet ( span) {
830+ p ! ( write( "{}" , snip) )
831+ } else {
832+ p ! ( write( "_" ) )
833+ }
834+ } else {
835+ p ! ( write( "_" ) )
836+ } ,
837+ }
838+ return Ok ( self ) ;
839+ }
840+ if let ConstValue :: Infer ( ..) = ct. val {
841+ p ! ( write( "_: " ) , print( ct. ty) ) ;
842+ return Ok ( self ) ;
843+ }
844+ if let ConstValue :: Param ( ParamConst { name, .. } ) = ct. val {
845+ p ! ( write( "{}" , name) ) ;
846+ return Ok ( self ) ;
847+ }
848+ if let ConstValue :: Scalar ( Scalar :: Bits { bits, .. } ) = ct. val {
849+ match ct. ty . sty {
850+ ty:: Bool => {
851+ p ! ( write( "{}" , if bits == 0 { "false" } else { "true" } ) ) ;
852+ return Ok ( self ) ;
853+ } ,
854+ ty:: Float ( ast:: FloatTy :: F32 ) => {
855+ p ! ( write( "{}f32" , Single :: from_bits( bits) ) ) ;
856+ return Ok ( self ) ;
857+ } ,
858+ ty:: Float ( ast:: FloatTy :: F64 ) => {
859+ p ! ( write( "{}f64" , Double :: from_bits( bits) ) ) ;
860+ return Ok ( self ) ;
861+ } ,
862+ ty:: Uint ( ui) => {
863+ p ! ( write( "{}{}" , bits, ui) ) ;
864+ return Ok ( self ) ;
865+ } ,
866+ ty:: Int ( i) =>{
867+ let ty = self . tcx ( ) . lift_to_global ( & ct. ty ) . unwrap ( ) ;
868+ let size = self . tcx ( ) . layout_of ( ty:: ParamEnv :: empty ( ) . and ( ty) )
869+ . unwrap ( )
870+ . size ;
871+ p ! ( write( "{}{}" , sign_extend( bits, size) as i128 , i) ) ;
872+ return Ok ( self ) ;
873+ } ,
874+ ty:: Char => {
875+ p ! ( write( "{:?}" , :: std:: char :: from_u32( bits as u32 ) . unwrap( ) ) ) ;
876+ return Ok ( self ) ;
877+ }
878+ _ => { } ,
879+ }
880+ }
881+ if let ty:: Ref ( _, ref_ty, _) = ct. ty . sty {
882+ let byte_str = match ( ct. val , & ref_ty. sty ) {
883+ ( ConstValue :: Scalar ( Scalar :: Ptr ( ptr) ) , ty:: Array ( t, n) ) if * t == u8 => {
884+ let n = n. unwrap_usize ( self . tcx ( ) ) ;
885+ Some ( self . tcx ( )
886+ . alloc_map . lock ( )
887+ . unwrap_memory ( ptr. alloc_id )
888+ . get_bytes ( & self . tcx ( ) , ptr, Size :: from_bytes ( n) ) . unwrap ( ) )
889+ } ,
890+ ( ConstValue :: Slice { data, start, end } , ty:: Slice ( t) ) if * t == u8 => {
891+ Some ( & data. bytes [ start..end] )
892+ } ,
893+ ( ConstValue :: Slice { data, start, end } , ty:: Str ) => {
894+ let slice = & data. bytes [ start..end] ;
895+ let s = :: std:: str:: from_utf8 ( slice)
896+ . expect ( "non utf8 str from miri" ) ;
897+ p ! ( write( "{:?}" , s) ) ;
898+ return Ok ( self ) ;
899+ } ,
900+ _ => None ,
901+ } ;
902+ if let Some ( byte_str) = byte_str {
903+ p ! ( write( "b\" " ) ) ;
904+ for & c in byte_str {
905+ for e in std:: ascii:: escape_default ( c) {
906+ self . write_char ( e as char ) ?;
907+ }
908+ }
909+ p ! ( write( "\" " ) ) ;
910+ return Ok ( self ) ;
911+ }
912+ }
913+ p ! ( write( "{:?} : " , ct. val) , print( ct. ty) ) ;
914+
915+ Ok ( self )
916+ }
811917}
812918
813919// HACK(eddyb) boxed to avoid moving around a large struct by-value.
@@ -900,6 +1006,7 @@ impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
9001006 type Region = Self ;
9011007 type Type = Self ;
9021008 type DynExistential = Self ;
1009+ type Const = Self ;
9031010
9041011 fn tcx ( & ' a self ) -> TyCtxt < ' a , ' gcx , ' tcx > {
9051012 self . tcx
@@ -975,6 +1082,13 @@ impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
9751082 self . pretty_print_dyn_existential ( predicates)
9761083 }
9771084
1085+ fn print_const (
1086+ self ,
1087+ ct : & ' tcx ty:: Const < ' tcx > ,
1088+ ) -> Result < Self :: Const , Self :: Error > {
1089+ self . pretty_print_const ( ct)
1090+ }
1091+
9781092 fn path_crate (
9791093 mut self ,
9801094 cnum : CrateNum ,
@@ -1448,6 +1562,7 @@ impl fmt::Display for ty::RegionKind {
14481562forward_display_to_print ! {
14491563 Ty <' tcx>,
14501564 & ' tcx ty:: List <ty:: ExistentialPredicate <' tcx>>,
1565+ & ' tcx ty:: Const <' tcx>,
14511566
14521567 // HACK(eddyb) these are exhaustive instead of generic,
14531568 // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet.
@@ -1537,106 +1652,6 @@ define_print_and_forward_display! {
15371652 p!( print_def_path( self . def_id, self . substs) ) ;
15381653 }
15391654
1540- & ' tcx ty:: Const <' tcx> {
1541- let u8 = cx. tcx( ) . types. u8 ;
1542- if let ty:: FnDef ( did, substs) = self . ty. sty {
1543- p!( print_value_path( did, substs) ) ;
1544- return Ok ( cx) ;
1545- }
1546- if let ConstValue :: Unevaluated ( did, substs) = self . val {
1547- match cx. tcx( ) . describe_def( did) {
1548- | Some ( Def :: Static ( _) )
1549- | Some ( Def :: Const ( _) )
1550- | Some ( Def :: AssociatedConst ( _) ) => p!( print_value_path( did, substs) ) ,
1551- _ => if did. is_local( ) {
1552- let span = cx. tcx( ) . def_span( did) ;
1553- if let Ok ( snip) = cx. tcx( ) . sess. source_map( ) . span_to_snippet( span) {
1554- p!( write( "{}" , snip) )
1555- } else {
1556- p!( write( "_" ) )
1557- }
1558- } else {
1559- p!( write( "_" ) )
1560- } ,
1561- }
1562- return Ok ( cx) ;
1563- }
1564- if let ConstValue :: Infer ( ..) = self . val {
1565- p!( write( "_: " ) , print( self . ty) ) ;
1566- return Ok ( cx) ;
1567- }
1568- if let ConstValue :: Param ( ParamConst { name, .. } ) = self . val {
1569- p!( write( "{}" , name) ) ;
1570- return Ok ( cx) ;
1571- }
1572- if let ConstValue :: Scalar ( Scalar :: Bits { bits, .. } ) = self . val {
1573- match self . ty. sty {
1574- ty:: Bool => {
1575- p!( write( "{}" , if bits == 0 { "false" } else { "true" } ) ) ;
1576- return Ok ( cx) ;
1577- } ,
1578- ty:: Float ( ast:: FloatTy :: F32 ) => {
1579- p!( write( "{}f32" , Single :: from_bits( bits) ) ) ;
1580- return Ok ( cx) ;
1581- } ,
1582- ty:: Float ( ast:: FloatTy :: F64 ) => {
1583- p!( write( "{}f64" , Double :: from_bits( bits) ) ) ;
1584- return Ok ( cx) ;
1585- } ,
1586- ty:: Uint ( ui) => {
1587- p!( write( "{}{}" , bits, ui) ) ;
1588- return Ok ( cx) ;
1589- } ,
1590- ty:: Int ( i) =>{
1591- let ty = cx. tcx( ) . lift_to_global( & self . ty) . unwrap( ) ;
1592- let size = cx. tcx( ) . layout_of( ty:: ParamEnv :: empty( ) . and( ty) )
1593- . unwrap( )
1594- . size;
1595- p!( write( "{}{}" , sign_extend( bits, size) as i128 , i) ) ;
1596- return Ok ( cx) ;
1597- } ,
1598- ty:: Char => {
1599- p!( write( "{:?}" , :: std:: char :: from_u32( bits as u32 ) . unwrap( ) ) ) ;
1600- return Ok ( cx) ;
1601- }
1602- _ => { } ,
1603- }
1604- }
1605- if let ty:: Ref ( _, ref_ty, _) = self . ty. sty {
1606- let byte_str = match ( self . val, & ref_ty. sty) {
1607- ( ConstValue :: Scalar ( Scalar :: Ptr ( ptr) ) , ty:: Array ( t, n) ) if * t == u8 => {
1608- let n = n. unwrap_usize( cx. tcx( ) ) ;
1609- Some ( cx. tcx( )
1610- . alloc_map. lock( )
1611- . unwrap_memory( ptr. alloc_id)
1612- . get_bytes( & cx. tcx( ) , ptr, Size :: from_bytes( n) ) . unwrap( ) )
1613- } ,
1614- ( ConstValue :: Slice { data, start, end } , ty:: Slice ( t) ) if * t == u8 => {
1615- Some ( & data. bytes[ start..end] )
1616- } ,
1617- ( ConstValue :: Slice { data, start, end } , ty:: Str ) => {
1618- let slice = & data. bytes[ start..end] ;
1619- let s = :: std:: str :: from_utf8( slice)
1620- . expect( "non utf8 str from miri" ) ;
1621- p!( write( "{:?}" , s) ) ;
1622- return Ok ( cx) ;
1623- } ,
1624- _ => None ,
1625- } ;
1626- if let Some ( byte_str) = byte_str {
1627- p!( write( "b\" " ) ) ;
1628- for & c in byte_str {
1629- for e in std:: ascii:: escape_default( c) {
1630- cx. write_char( e as char ) ?;
1631- }
1632- }
1633- p!( write( "\" " ) ) ;
1634- return Ok ( cx) ;
1635- }
1636- }
1637- p!( write( "{:?} : " , self . val) , print( self . ty) ) ;
1638- }
1639-
16401655 ty:: ParamTy {
16411656 p!( write( "{}" , self . name) )
16421657 }
0 commit comments