@@ -12,8 +12,8 @@ use rustc_middle::mir::AssertMessage;
1212use rustc_middle:: mir:: interpret:: ReportedErrorInfo ;
1313use rustc_middle:: query:: TyCtxtAt ;
1414use rustc_middle:: ty:: layout:: { HasTypingEnv , TyAndLayout , ValidityRequirement } ;
15- use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
16- use rustc_middle:: { bug, mir} ;
15+ use rustc_middle:: ty:: { self , FieldInfo , Ty , TyCtxt } ;
16+ use rustc_middle:: { bug, mir, span_bug } ;
1717use rustc_span:: { Span , Symbol , sym} ;
1818use rustc_target:: callconv:: FnAbi ;
1919use tracing:: debug;
@@ -23,8 +23,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
2323use crate :: interpret:: {
2424 self , AllocId , AllocInit , AllocRange , ConstAllocation , CtfeProvenance , FnArg , Frame ,
2525 GlobalAlloc , ImmTy , InterpCx , InterpResult , OpTy , PlaceTy , Pointer , RangeSet , Scalar ,
26- compile_time_machine, err_inval, interp_ok, throw_exhaust, throw_inval, throw_ub,
27- throw_ub_custom, throw_unsup, throw_unsup_format, type_implements_dyn_trait,
26+ compile_time_machine, ensure_monomorphic_enough, err_inval, interp_ok, throw_exhaust,
27+ throw_inval, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
28+ type_implements_dyn_trait,
2829} ;
2930
3031/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -619,6 +620,27 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
619620 ecx. write_type_info ( ty, dest) ?;
620621 }
621622
623+ sym:: field_offset => {
624+ let frt_ty = instance. args . type_at ( 0 ) ;
625+ ensure_monomorphic_enough ( ecx. tcx . tcx , frt_ty) ?;
626+
627+ let ( ty, variant, field) = if let ty:: Adt ( def, args) = frt_ty. kind ( )
628+ && let Some ( FieldInfo { base, variant_idx, field_idx, .. } ) =
629+ def. field_representing_type_info ( ecx. tcx . tcx , args)
630+ {
631+ ( base, variant_idx, field_idx)
632+ } else {
633+ span_bug ! ( ecx. cur_span( ) , "expected field representing type, got {frt_ty}" )
634+ } ;
635+ let layout = ecx. layout_of ( ty) ?;
636+ let cx = ty:: layout:: LayoutCx :: new ( ecx. tcx . tcx , ecx. typing_env ( ) ) ;
637+
638+ let layout = layout. for_variant ( & cx, variant) ;
639+ let offset = layout. fields . offset ( field. index ( ) ) . bytes ( ) ;
640+
641+ ecx. write_scalar ( Scalar :: from_target_usize ( offset, ecx) , dest) ?;
642+ }
643+
622644 _ => {
623645 // We haven't handled the intrinsic, let's see if we can use a fallback body.
624646 if ecx. tcx . intrinsic ( instance. def_id ( ) ) . unwrap ( ) . must_be_overridden {
0 commit comments