@@ -9,7 +9,7 @@ use rustc_middle::{bug, span_bug};
99use rustc_span:: symbol:: sym;
1010use tracing:: trace;
1111
12- use super :: { err_ub, throw_ub, ImmTy , InterpCx , Machine } ;
12+ use super :: { err_ub, throw_ub, ImmTy , InterpCx , Machine , MemPlaceMeta } ;
1313
1414impl < ' tcx , M : Machine < ' tcx > > InterpCx < ' tcx , M > {
1515 fn three_way_compare < T : Ord > ( & self , lhs : T , rhs : T ) -> ImmTy < ' tcx , M :: Provenance > {
@@ -415,11 +415,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
415415 use rustc_middle:: mir:: UnOp :: * ;
416416
417417 let layout = val. layout ;
418- let val = val. to_scalar ( ) ;
419418 trace ! ( "Running unary op {:?}: {:?} ({})" , un_op, val, layout. ty) ;
420419
421420 match layout. ty . kind ( ) {
422421 ty:: Bool => {
422+ let val = val. to_scalar ( ) ;
423423 let val = val. to_bool ( ) ?;
424424 let res = match un_op {
425425 Not => !val,
@@ -428,6 +428,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
428428 Ok ( ImmTy :: from_bool ( res, * self . tcx ) )
429429 }
430430 ty:: Float ( fty) => {
431+ let val = val. to_scalar ( ) ;
431432 // No NaN adjustment here, `-` is a bitwise operation!
432433 let res = match ( un_op, fty) {
433434 ( Neg , FloatTy :: F32 ) => Scalar :: from_f32 ( -val. to_f32 ( ) ?) ,
@@ -436,8 +437,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
436437 } ;
437438 Ok ( ImmTy :: from_scalar ( res, layout) )
438439 }
439- _ => {
440- assert ! ( layout . ty . is_integral ( ) ) ;
440+ _ if layout . ty . is_integral ( ) => {
441+ let val = val . to_scalar ( ) ;
441442 let val = val. to_bits ( layout. size ) ?;
442443 let res = match un_op {
443444 Not => self . truncate ( !val, layout) , // bitwise negation, then truncate
@@ -450,9 +451,28 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
450451 // Truncate to target type.
451452 self . truncate ( res, layout)
452453 }
454+ _ => span_bug ! ( self . cur_span( ) , "Invalid integer op {:?}" , un_op) ,
453455 } ;
454456 Ok ( ImmTy :: from_uint ( res, layout) )
455457 }
458+ ty:: RawPtr ( ..) => {
459+ assert_eq ! ( un_op, PtrMetadata ) ;
460+ let ( _, meta) = val. to_scalar_and_meta ( ) ;
461+ Ok ( match meta {
462+ MemPlaceMeta :: Meta ( scalar) => {
463+ let ty = un_op. ty ( * self . tcx , val. layout . ty ) ;
464+ let layout = self . layout_of ( ty) ?;
465+ ImmTy :: from_scalar ( scalar, layout)
466+ }
467+ MemPlaceMeta :: None => {
468+ let unit_layout = self . layout_of ( self . tcx . types . unit ) ?;
469+ ImmTy :: uninit ( unit_layout)
470+ }
471+ } )
472+ }
473+ _ => {
474+ bug ! ( "Unexpected unary op argument {val:?}" )
475+ }
456476 }
457477 }
458478}
0 commit comments