diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index ada9a0f887a1..6449b7cdebca 100644 --- a/compiler/rustc_mir/src/const_eval/machine.rs +++ b/compiler/rustc_mir/src/const_eval/machine.rs @@ -38,6 +38,10 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { if instance.def.requires_caller_location(self.tcx()) { return Ok(false); } + // only memoize instrinsics + if !matches!(instance.def, InstanceDef::Intrinsic(_)) { + return Ok(false); + } // For the moment we only do this for functions which take no arguments // (or all arguments are ZSTs) so that we don't memoize too much. if args.iter().any(|a| !a.layout.is_zst()) { @@ -232,13 +236,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, if ecx.tcx.is_const_fn_raw(def.did) { // If this function is a `const fn` then under certain circumstances we // can evaluate call via the query system, thus memoizing all future calls. - match instance.def { - InstanceDef::Intrinsic(_) => { - if ecx.try_eval_const_fn_call(instance, ret, args)? { - return Ok(None); - } - } - _ => {} + if ecx.try_eval_const_fn_call(instance, ret, args)? { + return Ok(None); } } else { // Some functions we support even if they are non-const -- but avoid testing diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs index 7cfe4734c1da..de7fb65f6858 100644 --- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs @@ -1,11 +1,11 @@ +// run-pass #![feature(core_intrinsics)] #![feature(const_heap)] #![feature(const_raw_ptr_deref)] #![feature(const_mut_refs)] use std::intrinsics; -const FOO: *const i32 = foo(); -//~^ error: untyped pointers are not allowed in constant +const FOO: &i32 = foo(); const fn foo() -> &'static i32 { let t = unsafe { @@ -16,5 +16,5 @@ const fn foo() -> &'static i32 { unsafe { &*t } } fn main() { - assert_eq!(unsafe { *FOO }, 20) + assert_eq!(*FOO, 20) } diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.stderr deleted file mode 100644 index cabd39dde31a..000000000000 --- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: untyped pointers are not allowed in constant - --> $DIR/alloc_intrinsic_nontransient.rs:7:1 - | -LL | const FOO: *const i32 = foo(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs new file mode 100644 index 000000000000..de7fb65f6858 --- /dev/null +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs @@ -0,0 +1,20 @@ +// run-pass +#![feature(core_intrinsics)] +#![feature(const_heap)] +#![feature(const_raw_ptr_deref)] +#![feature(const_mut_refs)] +use std::intrinsics; + +const FOO: &i32 = foo(); + +const fn foo() -> &'static i32 { + let t = unsafe { + let i = intrinsics::const_allocate(4, 4) as * mut i32; + *i = 20; + i + }; + unsafe { &*t } +} +fn main() { + assert_eq!(*FOO, 20) +}