22//! All high-level functions to read from memory work on operands as sources.
33
44use std:: assert_matches:: assert_matches;
5+ use std:: collections:: hash_map:: Entry ;
56
67use either:: { Either , Left , Right } ;
78
@@ -13,9 +14,9 @@ use rustc_middle::{mir, ty};
1314use rustc_target:: abi:: { self , Abi , HasDataLayout , Size } ;
1415
1516use super :: {
16- alloc_range, from_known_layout, mir_assign_valid_types, AllocId , Frame , InterpCx , InterpResult ,
17- MPlaceTy , Machine , MemPlace , MemPlaceMeta , OffsetMode , PlaceTy , Pointer , Projectable ,
18- Provenance , Scalar ,
17+ alloc_range, from_known_layout, mir_assign_valid_types, AllocId , ConstAllocation , Frame ,
18+ InterpCx , InterpResult , MPlaceTy , Machine , MemPlace , MemPlaceMeta , OffsetMode , PlaceTy ,
19+ Pointer , Projectable , Provenance , Scalar ,
1920} ;
2021
2122/// An `Immediate` represents a single immediate self-contained Rust value.
@@ -748,10 +749,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
748749 } )
749750 } ;
750751 let layout = from_known_layout ( self . tcx , self . param_env , layout, || self . layout_of ( ty) ) ?;
751- let span = self . cur_span ( ) ;
752- if let Some ( op) = self . const_cache . lock ( ) . get ( & ( val_val, layout, span) ) . cloned ( ) {
753- return Ok ( op) ;
754- }
755752 let imm = match val_val {
756753 mir:: ConstValue :: Indirect { alloc_id, offset } => {
757754 // We rely on mutability being set correctly in that allocation to prevent writes
@@ -761,16 +758,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
761758 }
762759 mir:: ConstValue :: Scalar ( x) => adjust_scalar ( x) ?. into ( ) ,
763760 mir:: ConstValue :: ZeroSized => Immediate :: Uninit ,
764- mir:: ConstValue :: Slice { data, meta } => {
761+ mir:: ConstValue :: Slice { data, meta } => self . const_slice_to_op ( data, meta) ?,
762+ } ;
763+ Ok ( OpTy { op : Operand :: Immediate ( imm) , layout } )
764+ }
765+
766+ fn const_slice_to_op (
767+ & self ,
768+ data : ConstAllocation < ' tcx > ,
769+ meta : u64 ,
770+ ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
771+ let span = self . cur_span ( ) ;
772+ let imm = match self . const_cache . lock ( ) . entry ( ( data, meta, span) ) {
773+ Entry :: Occupied ( e) => e. get ( ) . clone ( ) ,
774+ Entry :: Vacant ( e) => {
765775 // We rely on mutability being set correctly in `data` to prevent writes
766776 // where none should happen.
767777 let ptr = Pointer :: new ( self . tcx . reserve_and_set_memory_alloc ( data) , Size :: ZERO ) ;
768- Immediate :: new_slice ( self . global_base_pointer ( ptr) ?. into ( ) , meta, self )
778+ let imm = Immediate :: new_slice ( self . global_base_pointer ( ptr) ?. into ( ) , meta, self ) ;
779+ e. insert ( imm. clone ( ) ) ;
780+ imm
769781 }
770782 } ;
771- let res = OpTy { op : Operand :: Immediate ( imm) , layout } ;
772- self . const_cache . lock ( ) . insert ( ( val_val, layout, span) , res. clone ( ) ) ;
773- Ok ( res)
783+ Ok ( imm)
774784 }
775785}
776786
0 commit comments