11use rustc_middle:: mir;
22use rustc_middle:: ty:: layout:: HasTyCtxt ;
3+ use rustc_middle:: ty:: InstanceDef ;
34use rustc_middle:: ty:: { self , Ty } ;
45use std:: borrow:: Borrow ;
56use std:: collections:: hash_map:: Entry ;
@@ -12,6 +13,7 @@ use rustc_hir::def_id::DefId;
1213use rustc_middle:: mir:: AssertMessage ;
1314use rustc_session:: Limit ;
1415use rustc_span:: symbol:: { sym, Symbol } ;
16+ use rustc_target:: abi:: { Align , Size } ;
1517
1618use crate :: interpret:: {
1719 self , compile_time_machine, AllocId , Allocation , Frame , GlobalId , ImmTy , InterpCx ,
@@ -37,6 +39,14 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
3739 if instance. def . requires_caller_location ( self . tcx ( ) ) {
3840 return Ok ( false ) ;
3941 }
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+ }
4050 // For the moment we only do this for functions which take no arguments
4151 // (or all arguments are ZSTs) so that we don't memoize too much.
4252 if args. iter ( ) . any ( |a| !a. layout . is_zst ( ) ) {
@@ -295,6 +305,22 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
295305 } ;
296306 ecx. write_scalar ( Scalar :: from_bool ( cmp) , dest) ?;
297307 }
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+ }
298324 _ => {
299325 return Err ( ConstEvalErrKind :: NeedsRfc ( format ! (
300326 "calling intrinsic `{}`" ,
0 commit comments