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()) {
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
+// 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 {
unsafe { &*t }
}
fn main() {
- assert_eq!(unsafe { *FOO }, 20)
+ assert_eq!(*FOO, 20)
}
+++ /dev/null
-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
-
--- /dev/null
+// 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)
+}