@@ -120,17 +120,19 @@ pub(crate) fn codegen_constant<'tcx>(
120120 ConstantKind :: Ty ( ct) => ct,
121121 ConstantKind :: Val ( val, ty) => return codegen_const_value ( fx, val, ty) ,
122122 } ;
123- let const_val = match const_. val {
124- ConstKind :: Value ( const_val) => const_val,
125- ConstKind :: Unevaluated ( ty:: Unevaluated { def, substs, promoted } ) if fx. tcx . is_static ( def. did ) => {
123+ match const_. val {
124+ ConstKind :: Value ( valtree) => codegen_valtree ( fx, valtree, const_. ty , constant. span ) ,
125+ ConstKind :: Unevaluated ( ty:: Unevaluated { def, substs, promoted } )
126+ if fx. tcx . is_static ( def. did ) =>
127+ {
126128 assert ! ( substs. is_empty( ) ) ;
127129 assert ! ( promoted. is_none( ) ) ;
128130
129- return codegen_static_ref ( fx, def. did , fx. layout_of ( const_. ty ) ) . to_cvalue ( fx) ;
131+ codegen_static_ref ( fx, def. did , fx. layout_of ( const_. ty ) ) . to_cvalue ( fx)
130132 }
131133 ConstKind :: Unevaluated ( unevaluated) => {
132134 match fx. tcx . const_eval_resolve ( ParamEnv :: reveal_all ( ) , unevaluated, None ) {
133- Ok ( const_val) => const_val,
135+ Ok ( const_val) => codegen_const_value ( fx , const_val, const_ . ty ) ,
134136 Err ( _) => {
135137 span_bug ! ( constant. span, "erroneous constant not captured by required_consts" ) ;
136138 }
@@ -141,9 +143,53 @@ pub(crate) fn codegen_constant<'tcx>(
141143 | ConstKind :: Bound ( _, _)
142144 | ConstKind :: Placeholder ( _)
143145 | ConstKind :: Error ( _) => unreachable ! ( "{:?}" , const_) ,
146+ }
147+ }
148+
149+ pub ( crate ) fn codegen_valtree < ' tcx > (
150+ fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
151+ valtree : ty:: ValTree < ' tcx > ,
152+ ty : Ty < ' tcx > ,
153+ span : Span ,
154+ ) -> CValue < ' tcx > {
155+ let layout = fx. layout_of ( ty) ;
156+ let tcx = fx. tcx ;
157+ let mut encode_slice = |valtree : ty:: ValTree < ' _ > | {
158+ let s: Vec < u8 > = valtree
159+ . unwrap_branch ( )
160+ . iter ( )
161+ . map ( |b| u8:: try_from ( b. unwrap_leaf ( ) ) . unwrap ( ) )
162+ . collect ( ) ;
163+ let alloc_id = fx. tcx . allocate_bytes ( & s) ;
164+
165+ let ptr = pointer_for_alloc_id ( fx, alloc_id, Mutability :: Not ) . get_addr ( fx) ;
166+ let len = fx. bcx . ins ( ) . iconst ( fx. pointer_type , i64:: try_from ( s. len ( ) ) . unwrap ( ) ) ;
167+ CValue :: by_val_pair ( ptr, len, layout)
144168 } ;
145169
146- codegen_const_value ( fx, const_val, const_. ty )
170+ match * ty. kind ( ) {
171+ ty:: Ref ( _, pointee, _) => match * pointee. kind ( ) {
172+ ty:: Str => encode_slice ( valtree) ,
173+ ty:: Slice ( elem_ty) if elem_ty == tcx. types . u8 => encode_slice ( valtree) ,
174+ ty:: Array ( elem_ty, _) if elem_ty == tcx. types . u8 => {
175+ let s: Vec < u8 > = valtree
176+ . unwrap_branch ( )
177+ . iter ( )
178+ . map ( |b| u8:: try_from ( b. unwrap_leaf ( ) ) . unwrap ( ) )
179+ . collect ( ) ;
180+ let alloc_id = fx. tcx . allocate_bytes ( & s) ;
181+ fx. cx . constants_cx . todo . push ( TodoItem :: Alloc ( alloc_id) ) ;
182+ let data_id = data_id_for_alloc_id ( fx. cx . module , alloc_id, Mutability :: Not ) ;
183+ let local_data_id = fx. cx . module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
184+ #[ cfg( debug_assertions) ]
185+ fx. add_comment ( local_data_id, format ! ( "{:?}" , alloc_id) ) ;
186+ let ptr = fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id) ;
187+ CValue :: by_val ( ptr, layout)
188+ }
189+ _ => span_bug ! ( span, "{}: {:?}" , ty, valtree) ,
190+ } ,
191+ _ => codegen_const_value ( fx, ConstValue :: Scalar ( valtree. unwrap_leaf ( ) . into ( ) ) , ty) ,
192+ }
147193}
148194
149195pub ( crate ) fn codegen_const_value < ' tcx > (
@@ -237,8 +283,16 @@ fn pointer_for_allocation<'tcx>(
237283 alloc : & ' tcx Allocation ,
238284) -> crate :: pointer:: Pointer {
239285 let alloc_id = fx. tcx . create_memory_alloc ( alloc) ;
286+ pointer_for_alloc_id ( fx, alloc_id, alloc. mutability )
287+ }
288+
289+ fn pointer_for_alloc_id < ' tcx > (
290+ fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
291+ alloc_id : AllocId ,
292+ mutability : Mutability ,
293+ ) -> crate :: pointer:: Pointer {
240294 fx. cx . constants_cx . todo . push ( TodoItem :: Alloc ( alloc_id) ) ;
241- let data_id = data_id_for_alloc_id ( fx. cx . module , alloc_id, alloc . mutability ) ;
295+ let data_id = data_id_for_alloc_id ( fx. cx . module , alloc_id, mutability) ;
242296
243297 let local_data_id = fx. cx . module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
244298 #[ cfg( debug_assertions) ]
@@ -420,17 +474,19 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
420474 assert ! ( cx. todo. is_empty( ) , "{:?}" , cx. todo) ;
421475}
422476
423- pub ( crate ) fn mir_operand_get_const_val < ' tcx > (
477+ pub ( crate ) fn mir_operand_get_const_int < ' tcx > (
424478 fx : & FunctionCx < ' _ , ' _ , ' tcx > ,
425479 operand : & Operand < ' tcx > ,
426- ) -> Option < ConstValue < ' tcx > > {
480+ ) -> Option < ty:: ScalarInt > {
481+ mir_operand_get_const ( fx, operand) ?. try_to_scalar_int ( )
482+ }
483+
484+ pub ( crate ) fn mir_operand_get_const < ' tcx > (
485+ _fx : & FunctionCx < ' _ , ' _ , ' tcx > ,
486+ operand : & Operand < ' tcx > ,
487+ ) -> Option < mir:: ConstantKind < ' tcx > > {
427488 match operand {
428489 Operand :: Copy ( _) | Operand :: Move ( _) => None ,
429- Operand :: Constant ( const_) => match const_. literal {
430- ConstantKind :: Ty ( const_) => {
431- fx. monomorphize ( const_) . eval ( fx. tcx , ParamEnv :: reveal_all ( ) ) . val . try_to_value ( )
432- }
433- ConstantKind :: Val ( val, _) => Some ( val) ,
434- } ,
490+ Operand :: Constant ( const_) => Some ( const_. literal ) ,
435491 }
436492}
0 commit comments