Skip to content

Commit

Permalink
Allow using fn pointers in const fn behind const_fn_ptr gate
Browse files Browse the repository at this point in the history
  • Loading branch information
gnzlbg committed Sep 20, 2019
1 parent ea3ba36 commit 9cf9030
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1407,11 +1407,23 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
}
}
ty::FnPtr(_) => {
let unleash_miri = self
.tcx
.sess
.opts
.debugging_opts
.unleash_the_miri_inside_of_you;
let const_fn_ptr = self.tcx.features().const_fn_ptr;
if self.mode.requires_const_checking() {
let mut err = self.tcx.sess.struct_span_err(
self.span,
&format!("function pointers are not allowed in const fn"));
err.emit();
if !(unleash_miri || const_fn_ptr) {
emit_feature_err(
&self.tcx.sess.parse_sess,
sym::const_fn_ptr,
self.span,
GateIssue::Language,
"function pointers in const fn are unstable",
);
}
}
}
_ => {
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,9 @@ declare_features! (
/// Allows macro invocations in `extern {}` blocks.
(active, macros_in_extern, "1.27.0", Some(49476), None),

/// Allows calling function pointers inside `const` functions.
(active, const_fn_ptr, "1.27.0", Some(51909), None),

/// Allows accessing fields of unions inside `const` functions.
(active, const_fn_union, "1.27.0", Some(51909), None),

Expand Down
1 change: 1 addition & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ symbols! {
const_compare_raw_pointers,
const_constructor,
const_fn,
const_fn_ptr,
const_fn_union,
const_generics,
const_indexing,
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/consts/const-eval/const_fn_ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// run-pass
#![feature(const_fn)]
#![feature(const_fn_ptr)]

const fn double(x: usize) -> usize { x * 2 }
const X: fn(usize) -> usize = double;

const fn bar(x: usize) -> usize {
X(x)
}

const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
x(y)
}

fn main() {
const Y: usize = bar(2);
assert_eq!(Y, 4);
const Z: usize = foo(double, 2);
assert_eq!(Z, 4);
}
15 changes: 15 additions & 0 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// run-pass

// FIXME: this should not pass

#![feature(const_fn)]
#![feature(const_fn_ptr)]

fn double(x: usize) -> usize { x * 2 }
const X: fn(usize) -> usize = double;

const fn bar(x: usize) -> usize {
X(x)
}

fn main() {}
20 changes: 20 additions & 0 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
warning: function is never used: `double`
--> $DIR/const_fn_ptr_fail.rs:8:1
|
LL | fn double(x: usize) -> usize { x * 2 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default

warning: constant item is never used: `X`
--> $DIR/const_fn_ptr_fail.rs:9:1
|
LL | const X: fn(usize) -> usize = double;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: function is never used: `bar`
--> $DIR/const_fn_ptr_fail.rs:11:1
|
LL | const fn bar(x: usize) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

21 changes: 21 additions & 0 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![feature(const_fn)]
#![feature(const_fn_ptr)]

fn double(x: usize) -> usize { x * 2 }
const X: fn(usize) -> usize = double;

const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
x(y)
}

const Y: usize = bar(X, 2);
//~^ ERROR any use of this value will cause an error

const Z: usize = bar(double, 2);
//~^ ERROR any use of this value will cause an error


fn main() {
assert_eq!(Y, 4);
assert_eq!(Z, 4);
}
28 changes: 28 additions & 0 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error: any use of this value will cause an error
--> $DIR/const_fn_ptr_fail2.rs:8:5
|
LL | x(y)
| ^^^^
| |
| calling non-const function `double`
| inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:11:18
...
LL | const Y: usize = bar(X, 2);
| ---------------------------
|
= note: `#[deny(const_err)]` on by default

error: any use of this value will cause an error
--> $DIR/const_fn_ptr_fail2.rs:8:5
|
LL | x(y)
| ^^^^
| |
| calling non-const function `double`
| inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:14:18
...
LL | const Z: usize = bar(double, 2);
| --------------------------------

error: aborting due to 2 previous errors

11 changes: 11 additions & 0 deletions src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(const_fn)]

fn main() {}

const fn foo() {}
const X: fn() = foo;

const fn bar() {
X()
//~^ ERROR function pointers in const fn are unstable
}
12 changes: 12 additions & 0 deletions src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: function pointers in const fn are unstable
--> $DIR/feature-gate-const_fn_ptr.rs:9:5
|
LL | X()
| ^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/51909
= help: add `#![feature(const_fn_ptr)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.

0 comments on commit 9cf9030

Please sign in to comment.