2
2
//! All high-level functions to read from memory work on operands as sources.
3
3
4
4
use std:: assert_matches:: assert_matches;
5
+ use std:: collections:: hash_map:: Entry ;
5
6
6
7
use either:: { Either , Left , Right } ;
7
8
@@ -13,9 +14,9 @@ use rustc_middle::{mir, ty};
13
14
use rustc_target:: abi:: { self , Abi , HasDataLayout , Size } ;
14
15
15
16
use 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 ,
19
20
} ;
20
21
21
22
/// 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> {
748
749
} )
749
750
} ;
750
751
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
- }
755
752
let imm = match val_val {
756
753
mir:: ConstValue :: Indirect { alloc_id, offset } => {
757
754
// 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> {
761
758
}
762
759
mir:: ConstValue :: Scalar ( x) => adjust_scalar ( x) ?. into ( ) ,
763
760
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) => {
765
775
// We rely on mutability being set correctly in `data` to prevent writes
766
776
// where none should happen.
767
777
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
769
781
}
770
782
} ;
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)
774
784
}
775
785
}
776
786
0 commit comments