@@ -7,10 +7,10 @@ use std::assert_matches::assert_matches;
77use rustc_abi:: { FieldIdx , HasDataLayout , Size } ;
88use rustc_apfloat:: ieee:: { Double , Half , Quad , Single } ;
99use rustc_middle:: mir:: interpret:: { CTFE_ALLOC_SALT , read_target_uint, write_target_uint} ;
10- use rustc_middle:: mir:: { self , BinOp , ConstValue , NonDivergingIntrinsic } ;
10+ use rustc_middle:: mir:: { self , BinOp , ConstValue , NonDivergingIntrinsic , NullOp } ;
1111use rustc_middle:: ty:: layout:: TyAndLayout ;
1212use rustc_middle:: ty:: { Ty , TyCtxt } ;
13- use rustc_middle:: { bug, ty} ;
13+ use rustc_middle:: { bug, err_inval , ty} ;
1414use rustc_span:: { Symbol , sym} ;
1515use tracing:: trace;
1616
@@ -637,6 +637,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
637637 rustc_apfloat:: Round :: NearestTiesToEven ,
638638 ) ?,
639639
640+ sym:: unaligned_field_offset => self . unaligned_field_offset ( instance, dest) ?,
641+
640642 // Unsupported intrinsic: skip the return_to_block below.
641643 _ => return interp_ok ( false ) ,
642644 }
@@ -646,6 +648,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
646648 interp_ok ( true )
647649 }
648650
651+ fn unaligned_field_offset (
652+ & mut self ,
653+ instance : ty:: Instance < ' tcx > ,
654+ dest : & PlaceTy < ' tcx , M :: Provenance > ,
655+ ) -> InterpResult < ' tcx , ( ) > {
656+ assert_eq ! ( instance. args. len( ) , 1 ) ;
657+ match instance. args . type_at ( 0 ) . kind ( ) {
658+ & ty:: Field ( container, field_path) => {
659+ let offset = self . nullary_op ( NullOp :: OffsetOf ( field_path) , container) ?;
660+ self . write_immediate ( * offset, dest)
661+ }
662+ _ => Err ( err_inval ! ( TooGeneric ) ) . into ( ) ,
663+ }
664+ }
665+
649666 pub ( super ) fn eval_nondiverging_intrinsic (
650667 & mut self ,
651668 intrinsic : & NonDivergingIntrinsic < ' tcx > ,
0 commit comments