@@ -18,15 +18,15 @@ use cbmc::goto_program::{
18
18
use cbmc:: MachineModel ;
19
19
use cbmc:: { btree_string_map, InternString , InternedString } ;
20
20
use num:: bigint:: BigInt ;
21
- use rustc_middle:: ty:: { TyCtxt , VtblEntry } ;
21
+ use rustc_middle:: ty:: { ParamEnv , TyCtxt , VtblEntry } ;
22
22
use rustc_smir:: rustc_internal;
23
23
use rustc_target:: abi:: { FieldsShape , TagEncoding , Variants } ;
24
24
use stable_mir:: abi:: { Primitive , Scalar , ValueAbi } ;
25
25
use stable_mir:: mir:: mono:: Instance ;
26
26
use stable_mir:: mir:: {
27
27
AggregateKind , BinOp , CastKind , NullOp , Operand , Place , PointerCoercion , Rvalue , UnOp ,
28
28
} ;
29
- use stable_mir:: ty:: { ClosureKind , Const , IntTy , RigidTy , Size , Ty , TyKind , UintTy , VariantIdx } ;
29
+ use stable_mir:: ty:: { ClosureKind , IntTy , RigidTy , Size , Ty , TyConst , TyKind , UintTy , VariantIdx } ;
30
30
use std:: collections:: BTreeMap ;
31
31
use tracing:: { debug, trace, warn} ;
32
32
@@ -161,7 +161,7 @@ impl<'tcx> GotocCtx<'tcx> {
161
161
}
162
162
163
163
/// Codegens expressions of the type `let a = [4u8; 6];`
164
- fn codegen_rvalue_repeat ( & mut self , op : & Operand , sz : & Const , loc : Location ) -> Expr {
164
+ fn codegen_rvalue_repeat ( & mut self , op : & Operand , sz : & TyConst , loc : Location ) -> Expr {
165
165
let op_expr = self . codegen_operand_stable ( op) ;
166
166
let width = sz. eval_target_usize ( ) . unwrap ( ) ;
167
167
op_expr. array_constant ( width) . with_location ( loc)
@@ -170,7 +170,7 @@ impl<'tcx> GotocCtx<'tcx> {
170
170
fn codegen_rvalue_len ( & mut self , p : & Place ) -> Expr {
171
171
let pt = self . place_ty_stable ( p) ;
172
172
match pt. kind ( ) {
173
- TyKind :: RigidTy ( RigidTy :: Array ( _, sz) ) => self . codegen_const ( & sz, None ) ,
173
+ TyKind :: RigidTy ( RigidTy :: Array ( _, sz) ) => self . codegen_const_ty ( & sz, None ) ,
174
174
TyKind :: RigidTy ( RigidTy :: Slice ( _) ) => {
175
175
unwrap_or_return_codegen_unimplemented ! ( self , self . codegen_place_stable( p) )
176
176
. fat_ptr_goto_expr
@@ -779,9 +779,10 @@ impl<'tcx> GotocCtx<'tcx> {
779
779
. with_size_of_annotation ( self . codegen_ty_stable ( * t) ) ,
780
780
NullOp :: AlignOf => Expr :: int_constant ( layout. align . abi . bytes ( ) , Type :: size_t ( ) ) ,
781
781
NullOp :: OffsetOf ( fields) => Expr :: int_constant (
782
- layout
782
+ self . tcx
783
783
. offset_of_subfield (
784
- self ,
784
+ ParamEnv :: reveal_all ( ) ,
785
+ layout,
785
786
fields. iter ( ) . map ( |( var_idx, field_idx) | {
786
787
(
787
788
rustc_internal:: internal ( self . tcx , var_idx) ,
@@ -814,6 +815,51 @@ impl<'tcx> GotocCtx<'tcx> {
814
815
}
815
816
}
816
817
UnOp :: Neg => self . codegen_operand_stable ( e) . neg ( ) ,
818
+ UnOp :: PtrMetadata => {
819
+ let src_goto_expr = self . codegen_operand_stable ( e) ;
820
+ let dst_goto_typ = self . codegen_ty_stable ( res_ty) ;
821
+ debug ! (
822
+ "PtrMetadata |{:?}| with result type |{:?}|" ,
823
+ src_goto_expr, dst_goto_typ
824
+ ) ;
825
+ if let Some ( _vtable_typ) =
826
+ src_goto_expr. typ ( ) . lookup_field_type ( "vtable" , & self . symbol_table )
827
+ {
828
+ let vtable_expr = src_goto_expr. member ( "vtable" , & self . symbol_table ) ;
829
+ let dst_components =
830
+ dst_goto_typ. lookup_components ( & self . symbol_table ) . unwrap ( ) ;
831
+ assert_eq ! ( dst_components. len( ) , 2 ) ;
832
+ assert_eq ! ( dst_components[ 0 ] . name( ) , "_vtable_ptr" ) ;
833
+ assert ! ( dst_components[ 0 ] . typ( ) . is_pointer( ) ) ;
834
+ assert_eq ! ( dst_components[ 1 ] . name( ) , "_phantom" ) ;
835
+ self . assert_is_rust_phantom_data_like ( & dst_components[ 1 ] . typ ( ) ) ;
836
+ Expr :: struct_expr (
837
+ dst_goto_typ,
838
+ btree_string_map ! [
839
+ ( "_vtable_ptr" , vtable_expr. cast_to( dst_components[ 0 ] . typ( ) ) ) ,
840
+ (
841
+ "_phantom" ,
842
+ Expr :: struct_expr(
843
+ dst_components[ 1 ] . typ( ) ,
844
+ [ ] . into( ) ,
845
+ & self . symbol_table
846
+ )
847
+ )
848
+ ] ,
849
+ & self . symbol_table ,
850
+ )
851
+ } else if let Some ( len_typ) =
852
+ src_goto_expr. typ ( ) . lookup_field_type ( "len" , & self . symbol_table )
853
+ {
854
+ assert_eq ! ( len_typ, dst_goto_typ) ;
855
+ src_goto_expr. member ( "len" , & self . symbol_table )
856
+ } else {
857
+ unreachable ! (
858
+ "fat pointer with neither vtable nor len: {:?}" ,
859
+ src_goto_expr
860
+ ) ;
861
+ }
862
+ }
817
863
} ,
818
864
Rvalue :: Discriminant ( p) => {
819
865
let place =
@@ -1453,7 +1499,7 @@ impl<'tcx> GotocCtx<'tcx> {
1453
1499
) => {
1454
1500
// Cast to a slice fat pointer.
1455
1501
assert_eq ! ( src_elt_type, dst_elt_type) ;
1456
- let dst_goto_len = self . codegen_const ( & src_elt_count, None ) ;
1502
+ let dst_goto_len = self . codegen_const_ty ( & src_elt_count, None ) ;
1457
1503
let src_pointee_ty = pointee_type_stable ( coerce_info. src_ty ) . unwrap ( ) ;
1458
1504
let dst_data_expr = if src_pointee_ty. kind ( ) . is_array ( ) {
1459
1505
src_goto_expr. cast_to ( self . codegen_ty_stable ( src_elt_type) . to_pointer ( ) )
0 commit comments