@@ -118,8 +118,14 @@ impl<Tag: Provenance> std::fmt::Display for ImmTy<'tcx, Tag> {
118118 ty : Ty < ' tcx > ,
119119 ) -> Result < FmtPrinter < ' a , ' tcx , F > , std:: fmt:: Error > {
120120 match s {
121- ScalarMaybeUninit :: Scalar ( s) => {
122- cx. pretty_print_const_scalar ( s. erase_for_fmt ( ) , ty, true )
121+ ScalarMaybeUninit :: Scalar ( Scalar :: Int ( int) ) => {
122+ cx. pretty_print_const_scalar_int ( int, ty, true )
123+ }
124+ ScalarMaybeUninit :: Scalar ( Scalar :: Ptr ( ptr, _sz) ) => {
125+ // Just print the ptr value. `pretty_print_const_scalar_ptr` would also try to
126+ // print what is points to, which would fail since it has no access to the local
127+ // memory.
128+ cx. pretty_print_const_pointer ( ptr, ty, true )
123129 }
124130 ScalarMaybeUninit :: Uninit => cx. typed_value (
125131 |mut this| {
@@ -139,11 +145,11 @@ impl<Tag: Provenance> std::fmt::Display for ImmTy<'tcx, Tag> {
139145 p ( cx, s, ty) ?;
140146 return Ok ( ( ) ) ;
141147 }
142- write ! ( f, "{}: {}" , s. erase_for_fmt ( ) , self . layout. ty)
148+ write ! ( f, "{}: {}" , s, self . layout. ty)
143149 }
144150 Immediate :: ScalarPair ( a, b) => {
145151 // FIXME(oli-obk): at least print tuples and slices nicely
146- write ! ( f, "({}, {}): {}" , a. erase_for_fmt ( ) , b. erase_for_fmt ( ) , self . layout. ty, )
152+ write ! ( f, "({}, {}): {}" , a, b, self . layout. ty, )
147153 }
148154 }
149155 } )
@@ -693,8 +699,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
693699 Ok ( match * tag_encoding {
694700 TagEncoding :: Direct => {
695701 let tag_bits = tag_val
696- . to_bits ( tag_layout. size )
697- . map_err ( |_| err_ub ! ( InvalidTag ( tag_val. erase_for_fmt( ) ) ) ) ?;
702+ . try_to_int ( )
703+ . map_err ( |dbg_val| err_ub ! ( InvalidTag ( dbg_val) ) ) ?
704+ . assert_bits ( tag_layout. size ) ;
698705 // Cast bits from tag layout to discriminant layout.
699706 let discr_val = self . cast_from_scalar ( tag_bits, tag_layout, discr_layout. ty ) ;
700707 let discr_bits = discr_val. assert_bits ( discr_layout. size ) ;
@@ -711,7 +718,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
711718 }
712719 _ => span_bug ! ( self . cur_span( ) , "tagged layout for non-adt non-generator" ) ,
713720 }
714- . ok_or_else ( || err_ub ! ( InvalidTag ( tag_val . erase_for_fmt ( ) ) ) ) ?;
721+ . ok_or_else ( || err_ub ! ( InvalidTag ( Scalar :: from_uint ( tag_bits , tag_layout . size ) ) ) ) ?;
715722 // Return the cast value, and the index.
716723 ( discr_val, index. 0 )
717724 }
@@ -720,18 +727,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
720727 // discriminant (encoded in niche/tag) and variant index are the same.
721728 let variants_start = niche_variants. start ( ) . as_u32 ( ) ;
722729 let variants_end = niche_variants. end ( ) . as_u32 ( ) ;
723- let variant = match tag_val. to_bits_or_ptr ( tag_layout. size ) {
724- Err ( ptr) => {
725- // The niche must be just 0 (which an inbounds pointer value never is)
730+ let variant = match tag_val. try_to_int ( ) {
731+ Err ( dbg_val) => {
732+ // So this is a pointer then, and casting to an int failed.
733+ // Can only happen during CTFE.
734+ let ptr = self . scalar_to_ptr ( tag_val) ;
735+ // The niche must be just 0, and the ptr not null, then we know this is
736+ // okay. Everything else, we conservatively reject.
726737 let ptr_valid = niche_start == 0
727738 && variants_start == variants_end
728- && !self . memory . ptr_may_be_null ( ptr. into ( ) ) ;
739+ && !self . memory . ptr_may_be_null ( ptr) ;
729740 if !ptr_valid {
730- throw_ub ! ( InvalidTag ( tag_val . erase_for_fmt ( ) ) )
741+ throw_ub ! ( InvalidTag ( dbg_val ) )
731742 }
732743 dataful_variant
733744 }
734745 Ok ( tag_bits) => {
746+ let tag_bits = tag_bits. assert_bits ( tag_layout. size ) ;
735747 // We need to use machine arithmetic to get the relative variant idx:
736748 // variant_index_relative = tag_val - niche_start_val
737749 let tag_val = ImmTy :: from_uint ( tag_bits, tag_layout) ;
0 commit comments