Skip to content

Commit 25bdd76

Browse files
authored
Rollup merge of rust-lang#64635 - gnzlbg:const_fn_ptr, r=oli-obk
Allow using fn pointers in const fn with unleash miri This allows using function pointers in const fns when `-Zunleash-the-miri-within-you` is enabled. If the call to the `const fn` happens in a `const`-context, the function pointer is required to point to a `const fn`: ```rust fn non_const_fn() -> i32 { 42 } const fn const_fn() -> i32 { 42 } const fn foo(x: fn() -> i32) -> i32 { x() } let x: i32 = foo(non_const_fn_ptr); // OK let y: i32 = foo(const_fn_ptr); // OK const X: i32 = foo(non_const_fn_ptr); // ERROR: `non_const_fn` is not `const fn` const Y: i32 = foo(const_fn_ptr); // OK ``` r? @oli-obk
2 parents 05d7ae2 + 9d4053f commit 25bdd76

File tree

6 files changed

+308
-2
lines changed

6 files changed

+308
-2
lines changed

Diff for: src/librustc_mir/transform/qualify_consts.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1407,10 +1407,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
14071407
}
14081408
}
14091409
ty::FnPtr(_) => {
1410-
if self.mode.requires_const_checking() {
1410+
let unleash_miri = self
1411+
.tcx
1412+
.sess
1413+
.opts
1414+
.debugging_opts
1415+
.unleash_the_miri_inside_of_you;
1416+
if self.mode.requires_const_checking() && !unleash_miri {
14111417
let mut err = self.tcx.sess.struct_span_err(
14121418
self.span,
1413-
&format!("function pointers are not allowed in const fn"));
1419+
"function pointers are not allowed in const fn"
1420+
);
14141421
err.emit();
14151422
}
14161423
}

Diff for: src/test/ui/consts/const-eval/const_fn_ptr.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// run-pass
2+
// compile-flags: -Zunleash-the-miri-inside-of-you
3+
#![feature(const_fn)]
4+
5+
fn double(x: usize) -> usize { x * 2 }
6+
const fn double_const(x: usize) -> usize { x * 2 }
7+
8+
const X: fn(usize) -> usize = double;
9+
const X_const: fn(usize) -> usize = double_const;
10+
11+
const fn bar(x: usize) -> usize {
12+
X(x)
13+
}
14+
15+
const fn bar_const(x: usize) -> usize {
16+
X_const(x)
17+
}
18+
19+
const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
20+
x(y)
21+
}
22+
23+
fn main() {
24+
const Y: usize = bar_const(2);
25+
assert_eq!(Y, 4);
26+
let y = bar_const(2);
27+
assert_eq!(y, 4);
28+
let y = bar(2);
29+
assert_eq!(y, 4);
30+
31+
const Z: usize = foo(double_const, 2);
32+
assert_eq!(Z, 4);
33+
let z = foo(double_const, 2);
34+
assert_eq!(z, 4);
35+
let z = foo(double, 2);
36+
assert_eq!(z, 4);
37+
}

Diff for: src/test/ui/consts/const-eval/const_fn_ptr.stderr

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
warning: skipping const checks
2+
--> $DIR/const_fn_ptr.rs:25:5
3+
|
4+
LL | assert_eq!(Y, 4);
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
8+
9+
warning: skipping const checks
10+
--> $DIR/const_fn_ptr.rs:25:5
11+
|
12+
LL | assert_eq!(Y, 4);
13+
| ^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
16+
17+
warning: skipping const checks
18+
--> $DIR/const_fn_ptr.rs:25:5
19+
|
20+
LL | assert_eq!(Y, 4);
21+
| ^^^^^^^^^^^^^^^^^
22+
|
23+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
24+
25+
warning: skipping const checks
26+
--> $DIR/const_fn_ptr.rs:27:5
27+
|
28+
LL | assert_eq!(y, 4);
29+
| ^^^^^^^^^^^^^^^^^
30+
|
31+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
32+
33+
warning: skipping const checks
34+
--> $DIR/const_fn_ptr.rs:27:5
35+
|
36+
LL | assert_eq!(y, 4);
37+
| ^^^^^^^^^^^^^^^^^
38+
|
39+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
40+
41+
warning: skipping const checks
42+
--> $DIR/const_fn_ptr.rs:27:5
43+
|
44+
LL | assert_eq!(y, 4);
45+
| ^^^^^^^^^^^^^^^^^
46+
|
47+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
48+
49+
warning: skipping const checks
50+
--> $DIR/const_fn_ptr.rs:29:5
51+
|
52+
LL | assert_eq!(y, 4);
53+
| ^^^^^^^^^^^^^^^^^
54+
|
55+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
56+
57+
warning: skipping const checks
58+
--> $DIR/const_fn_ptr.rs:29:5
59+
|
60+
LL | assert_eq!(y, 4);
61+
| ^^^^^^^^^^^^^^^^^
62+
|
63+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
64+
65+
warning: skipping const checks
66+
--> $DIR/const_fn_ptr.rs:29:5
67+
|
68+
LL | assert_eq!(y, 4);
69+
| ^^^^^^^^^^^^^^^^^
70+
|
71+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
72+
73+
warning: skipping const checks
74+
--> $DIR/const_fn_ptr.rs:32:5
75+
|
76+
LL | assert_eq!(Z, 4);
77+
| ^^^^^^^^^^^^^^^^^
78+
|
79+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
80+
81+
warning: skipping const checks
82+
--> $DIR/const_fn_ptr.rs:32:5
83+
|
84+
LL | assert_eq!(Z, 4);
85+
| ^^^^^^^^^^^^^^^^^
86+
|
87+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
88+
89+
warning: skipping const checks
90+
--> $DIR/const_fn_ptr.rs:32:5
91+
|
92+
LL | assert_eq!(Z, 4);
93+
| ^^^^^^^^^^^^^^^^^
94+
|
95+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
96+
97+
warning: skipping const checks
98+
--> $DIR/const_fn_ptr.rs:34:5
99+
|
100+
LL | assert_eq!(z, 4);
101+
| ^^^^^^^^^^^^^^^^^
102+
|
103+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
104+
105+
warning: skipping const checks
106+
--> $DIR/const_fn_ptr.rs:34:5
107+
|
108+
LL | assert_eq!(z, 4);
109+
| ^^^^^^^^^^^^^^^^^
110+
|
111+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
112+
113+
warning: skipping const checks
114+
--> $DIR/const_fn_ptr.rs:34:5
115+
|
116+
LL | assert_eq!(z, 4);
117+
| ^^^^^^^^^^^^^^^^^
118+
|
119+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
120+
121+
warning: skipping const checks
122+
--> $DIR/const_fn_ptr.rs:36:5
123+
|
124+
LL | assert_eq!(z, 4);
125+
| ^^^^^^^^^^^^^^^^^
126+
|
127+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
128+
129+
warning: skipping const checks
130+
--> $DIR/const_fn_ptr.rs:36:5
131+
|
132+
LL | assert_eq!(z, 4);
133+
| ^^^^^^^^^^^^^^^^^
134+
|
135+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
136+
137+
warning: skipping const checks
138+
--> $DIR/const_fn_ptr.rs:36:5
139+
|
140+
LL | assert_eq!(z, 4);
141+
| ^^^^^^^^^^^^^^^^^
142+
|
143+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
144+
145+
warning: constant `X_const` should have an upper case name
146+
--> $DIR/const_fn_ptr.rs:9:7
147+
|
148+
LL | const X_const: fn(usize) -> usize = double_const;
149+
| ^^^^^^^ help: convert the identifier to upper case: `X_CONST`
150+
|
151+
= note: `#[warn(non_upper_case_globals)]` on by default
152+

Diff for: src/test/ui/consts/const-eval/const_fn_ptr_fail.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-pass
2+
// compile-flags: -Zunleash-the-miri-inside-of-you
3+
#![feature(const_fn)]
4+
#![allow(unused)]
5+
6+
fn double(x: usize) -> usize { x * 2 }
7+
const X: fn(usize) -> usize = double;
8+
9+
const fn bar(x: usize) -> usize {
10+
X(x) // FIXME: this should error someday
11+
}
12+
13+
fn main() {}

Diff for: src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// compile-flags: -Zunleash-the-miri-inside-of-you
2+
#![feature(const_fn)]
3+
#![allow(const_err)]
4+
5+
fn double(x: usize) -> usize { x * 2 }
6+
const X: fn(usize) -> usize = double;
7+
8+
const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
9+
x(y)
10+
}
11+
12+
const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
13+
const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
14+
15+
fn main() {
16+
assert_eq!(Y, 4);
17+
//~^ ERROR evaluation of constant expression failed
18+
//~^^ WARN skipping const checks
19+
//~^^^ WARN skipping const checks
20+
//~^^^^ WARN skipping const checks
21+
assert_eq!(Z, 4);
22+
//~^ ERROR evaluation of constant expression failed
23+
//~^^ WARN skipping const checks
24+
//~^^^ WARN skipping const checks
25+
//~^^^^ WARN skipping const checks
26+
}
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
warning: skipping const checks
2+
--> $DIR/const_fn_ptr_fail2.rs:16:5
3+
|
4+
LL | assert_eq!(Y, 4);
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
8+
9+
warning: skipping const checks
10+
--> $DIR/const_fn_ptr_fail2.rs:16:5
11+
|
12+
LL | assert_eq!(Y, 4);
13+
| ^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
16+
17+
warning: skipping const checks
18+
--> $DIR/const_fn_ptr_fail2.rs:16:5
19+
|
20+
LL | assert_eq!(Y, 4);
21+
| ^^^^^^^^^^^^^^^^^
22+
|
23+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
24+
25+
warning: skipping const checks
26+
--> $DIR/const_fn_ptr_fail2.rs:21:5
27+
|
28+
LL | assert_eq!(Z, 4);
29+
| ^^^^^^^^^^^^^^^^^
30+
|
31+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
32+
33+
warning: skipping const checks
34+
--> $DIR/const_fn_ptr_fail2.rs:21:5
35+
|
36+
LL | assert_eq!(Z, 4);
37+
| ^^^^^^^^^^^^^^^^^
38+
|
39+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
40+
41+
warning: skipping const checks
42+
--> $DIR/const_fn_ptr_fail2.rs:21:5
43+
|
44+
LL | assert_eq!(Z, 4);
45+
| ^^^^^^^^^^^^^^^^^
46+
|
47+
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
48+
49+
error[E0080]: evaluation of constant expression failed
50+
--> $DIR/const_fn_ptr_fail2.rs:16:5
51+
|
52+
LL | assert_eq!(Y, 4);
53+
| ^^^^^^^^^^^-^^^^^
54+
| |
55+
| referenced constant has errors
56+
|
57+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
58+
59+
error[E0080]: evaluation of constant expression failed
60+
--> $DIR/const_fn_ptr_fail2.rs:21:5
61+
|
62+
LL | assert_eq!(Z, 4);
63+
| ^^^^^^^^^^^-^^^^^
64+
| |
65+
| referenced constant has errors
66+
|
67+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
68+
69+
error: aborting due to 2 previous errors
70+
71+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)