1
1
use rustc_middle:: mir;
2
2
use rustc_middle:: ty:: layout:: HasTyCtxt ;
3
+ use rustc_middle:: ty:: InstanceDef ;
3
4
use rustc_middle:: ty:: { self , Ty } ;
4
5
use std:: borrow:: Borrow ;
5
6
use std:: collections:: hash_map:: Entry ;
@@ -12,6 +13,7 @@ use rustc_hir::def_id::DefId;
12
13
use rustc_middle:: mir:: AssertMessage ;
13
14
use rustc_session:: Limit ;
14
15
use rustc_span:: symbol:: { sym, Symbol } ;
16
+ use rustc_target:: abi:: { Align , Size } ;
15
17
16
18
use crate :: interpret:: {
17
19
self , compile_time_machine, AllocId , Allocation , Frame , GlobalId , ImmTy , InterpCx ,
@@ -37,6 +39,14 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
37
39
if instance. def . requires_caller_location ( self . tcx ( ) ) {
38
40
return Ok ( false ) ;
39
41
}
42
+ // Only memoize instrinsics. This was added in #79594 while adding the `const_allocate` intrinsic.
43
+ // We only memoize intrinsics because it would be unsound to memoize functions
44
+ // which might interact with the heap.
45
+ // Additionally, const_allocate intrinsic is impure and thus should not be memoized;
46
+ // it will not be memoized because it has non-ZST args
47
+ if !matches ! ( instance. def, InstanceDef :: Intrinsic ( _) ) {
48
+ return Ok ( false ) ;
49
+ }
40
50
// For the moment we only do this for functions which take no arguments
41
51
// (or all arguments are ZSTs) so that we don't memoize too much.
42
52
if args. iter ( ) . any ( |a| !a. layout . is_zst ( ) ) {
@@ -295,6 +305,22 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
295
305
} ;
296
306
ecx. write_scalar ( Scalar :: from_bool ( cmp) , dest) ?;
297
307
}
308
+ sym:: const_allocate => {
309
+ let size = ecx. read_scalar ( args[ 0 ] ) ?. to_machine_usize ( ecx) ?;
310
+ let align = ecx. read_scalar ( args[ 1 ] ) ?. to_machine_usize ( ecx) ?;
311
+
312
+ let align = match Align :: from_bytes ( align) {
313
+ Ok ( a) => a,
314
+ Err ( err) => throw_ub_format ! ( "align has to be a power of 2, {}" , err) ,
315
+ } ;
316
+
317
+ let ptr = ecx. memory . allocate (
318
+ Size :: from_bytes ( size as u64 ) ,
319
+ align,
320
+ interpret:: MemoryKind :: ConstHeap ,
321
+ ) ;
322
+ ecx. write_scalar ( Scalar :: Ptr ( ptr) , dest) ?;
323
+ }
298
324
_ => {
299
325
return Err ( ConstEvalErrKind :: NeedsRfc ( format ! (
300
326
"calling intrinsic `{}`" ,
0 commit comments