@@ -2,7 +2,8 @@ use crate::lower1::context::Definitions;
22use rustc_abi:: { BackendRepr , FieldIdx , FieldsShape , Size , TagEncoding , VariantIdx , Variants } ;
33use rustc_hash:: FxHashMap as HashMap ;
44use rustc_middle:: mir:: interpret:: {
5- AllocId , AllocRange , Allocation , CtfeProvenance , GlobalAlloc , Pointer , Provenance , Scalar ,
5+ AllocId , AllocInit , AllocRange , Allocation , CtfeProvenance , GlobalAlloc , Pointer , Provenance ,
6+ Scalar ,
67} ;
78use rustc_middle:: ty:: consts:: ConstExt ;
89use rustc_middle:: ty:: layout:: TyAndLayout ;
@@ -67,9 +68,7 @@ fn anonymous_memory_identity(
6768 Some ( format ! ( "{}::memory::{hash}" , tcx. crate_name( LOCAL_CRATE ) ) )
6869}
6970
70- /// Decode the optimized `ConstValue::Slice` representation. Rust uses that
71- /// representation for every reference whose pointee has a slice tail, not
72- /// merely for `&str` and `&[T]`.
71+ /// Decode a pointer-valued scalar, including aggregates with a scalar ABI.
7372pub fn read_pointer_constant < ' tcx > (
7473 tcx : TyCtxt < ' tcx > ,
7574 pointer : Pointer < CtfeProvenance > ,
@@ -89,10 +88,6 @@ pub fn read_pointer_constant<'tcx>(
8988 if let TyKind :: Pat ( inner, _) = ty. kind ( ) {
9089 return read_pointer_constant ( tcx, pointer, * inner, oomir_data_types, instance) ;
9190 }
92- if let Some ( field_ty) = scalar_struct_field_ty ( tcx, ty) ? {
93- return read_pointer_constant ( tcx, pointer, field_ty, oomir_data_types, instance) ;
94- }
95-
9691 match ty. kind ( ) {
9792 TyKind :: FnPtr ( ..) => {
9893 read_function_pointer_constant ( tcx, pointer, ty, oomir_data_types, instance)
@@ -143,7 +138,39 @@ pub fn read_pointer_constant<'tcx>(
143138 )
144139 }
145140 }
146- _ => read_pointee_constant ( tcx, pointer, ty, oomir_data_types, instance) ,
141+ _ => {
142+ let layout = tcx
143+ . layout_of ( TypingEnv :: fully_monomorphized ( ) . as_query_input ( ty) )
144+ . map_err ( |error| format ! ( "Could not determine scalar constant layout: {error:?}" ) ) ?;
145+ if !matches ! ( layout. backend_repr, BackendRepr :: Scalar ( _) )
146+ || layout. size != tcx. data_layout . pointer_size ( )
147+ {
148+ return Err ( format ! ( "Unexpected pointer scalar for constant type {ty:?}" ) ) ;
149+ }
150+ // This pointer is the aggregate's contents, not its address. Put
151+ // the scalar in temporary storage so the normal decoder preserves
152+ // enum niches, field types, and function-pointer provenance.
153+ let mut allocation =
154+ ConstAllocation :: new ( layout. size , layout. align . abi , AllocInit :: Uninit , ( ) ) ;
155+ allocation
156+ . write_scalar (
157+ & tcx. data_layout ,
158+ AllocRange {
159+ start : Size :: ZERO ,
160+ size : layout. size ,
161+ } ,
162+ Scalar :: from_pointer ( pointer, & tcx. data_layout ) ,
163+ )
164+ . map_err ( |error| format ! ( "Could not store pointer scalar: {error:?}" ) ) ?;
165+ read_constant_value_from_memory (
166+ tcx,
167+ & allocation,
168+ Size :: ZERO ,
169+ ty,
170+ oomir_data_types,
171+ instance,
172+ )
173+ }
147174 }
148175}
149176
0 commit comments