Skip to content

Commit 85a59d4

Browse files
authored
Rollup merge of #77170 - ecstatic-morse:const-fn-ptr, r=oli-obk
Remove `#[rustc_allow_const_fn_ptr]` and add `#![feature(const_fn_fn_ptr_basics)]` `rustc_allow_const_fn_ptr` was a hack to work around the lack of an escape hatch for the "min `const fn`" checks in const-stable functions. Now that we have co-opted `allow_internal_unstable` for this purpose, we no longer need a bespoke attribute. Now this functionality is gated under `const_fn_fn_ptr_basics` (how concise!), and `#[allow_internal_unstable(const_fn_fn_ptr_basics)]` replaces `#[rustc_allow_const_fn_ptr]`. `const_fn_fn_ptr_basics` allows function pointer types to appear in the arguments and locals of a `const fn` as well as function pointer casts to be performed inside a `const fn`. Both of these were allowed in constants and statics already. Notably, this does **not** allow users to invoke function pointers in a const context. Presumably, we will use a nicer name for that (`const_fn_ptr`?). r? @oli-obk
2 parents 88ae20d + 807260b commit 85a59d4

39 files changed

+146
-135
lines changed

compiler/rustc_attr/src/builtin.rs

+7-24
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ pub struct ConstStability {
145145
pub feature: Symbol,
146146
/// whether the function has a `#[rustc_promotable]` attribute
147147
pub promotable: bool,
148-
/// whether the function has a `#[rustc_allow_const_fn_ptr]` attribute
149-
pub allow_const_fn_ptr: bool,
150148
}
151149

152150
/// The available stability levels.
@@ -190,7 +188,6 @@ where
190188
let mut stab: Option<Stability> = None;
191189
let mut const_stab: Option<ConstStability> = None;
192190
let mut promotable = false;
193-
let mut allow_const_fn_ptr = false;
194191
let diagnostic = &sess.parse_sess.span_diagnostic;
195192

196193
'outer: for attr in attrs_iter {
@@ -200,7 +197,6 @@ where
200197
sym::unstable,
201198
sym::stable,
202199
sym::rustc_promotable,
203-
sym::rustc_allow_const_fn_ptr,
204200
]
205201
.iter()
206202
.any(|&s| attr.has_name(s))
@@ -215,9 +211,6 @@ where
215211
if attr.has_name(sym::rustc_promotable) {
216212
promotable = true;
217213
}
218-
if attr.has_name(sym::rustc_allow_const_fn_ptr) {
219-
allow_const_fn_ptr = true;
220-
}
221214
// attributes with data
222215
else if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta {
223216
let meta = meta.as_ref().unwrap();
@@ -360,12 +353,8 @@ where
360353
if sym::unstable == meta_name {
361354
stab = Some(Stability { level, feature });
362355
} else {
363-
const_stab = Some(ConstStability {
364-
level,
365-
feature,
366-
promotable: false,
367-
allow_const_fn_ptr: false,
368-
});
356+
const_stab =
357+
Some(ConstStability { level, feature, promotable: false });
369358
}
370359
}
371360
(None, _, _) => {
@@ -440,12 +429,8 @@ where
440429
if sym::stable == meta_name {
441430
stab = Some(Stability { level, feature });
442431
} else {
443-
const_stab = Some(ConstStability {
444-
level,
445-
feature,
446-
promotable: false,
447-
allow_const_fn_ptr: false,
448-
});
432+
const_stab =
433+
Some(ConstStability { level, feature, promotable: false });
449434
}
450435
}
451436
(None, _) => {
@@ -464,18 +449,16 @@ where
464449
}
465450

466451
// Merge the const-unstable info into the stability info
467-
if promotable || allow_const_fn_ptr {
452+
if promotable {
468453
if let Some(ref mut stab) = const_stab {
469454
stab.promotable = promotable;
470-
stab.allow_const_fn_ptr = allow_const_fn_ptr;
471455
} else {
472456
struct_span_err!(
473457
diagnostic,
474458
item_sp,
475459
E0717,
476-
"rustc_promotable and rustc_allow_const_fn_ptr attributes \
477-
must be paired with either a rustc_const_unstable or a rustc_const_stable \
478-
attribute"
460+
"`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` \
461+
or a `rustc_const_stable` attribute"
479462
)
480463
.emit();
481464
}

compiler/rustc_feature/src/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,9 @@ declare_features! (
587587
/// Allows basic arithmetic on floating point types in a `const fn`.
588588
(active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
589589

590+
/// Allows using and casting function pointers in a `const fn`.
591+
(active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
592+
590593
// -------------------------------------------------------------------------
591594
// feature-group-end: actual feature gates
592595
// -------------------------------------------------------------------------

compiler/rustc_feature/src/builtin_attrs.rs

-1
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
464464
// ==========================================================================
465465

466466
rustc_attr!(rustc_promotable, AssumedUsed, template!(Word), IMPL_DETAIL),
467-
rustc_attr!(rustc_allow_const_fn_ptr, AssumedUsed, template!(Word), IMPL_DETAIL),
468467
rustc_attr!(rustc_args_required_const, AssumedUsed, template!(List: "N"), INTERNAL_UNSTABLE),
469468

470469
// ==========================================================================

compiler/rustc_middle/src/query/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,6 @@ rustc_queries! {
457457
desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) }
458458
}
459459

460-
query const_fn_is_allowed_fn_ptr(key: DefId) -> bool {
461-
desc { |tcx| "checking if const fn allows `fn()` types: `{}`", tcx.def_path_str(key) }
462-
}
463-
464460
/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
465461
query is_foreign_item(key: DefId) -> bool {
466462
desc { |tcx| "checking if `{}` is a foreign item", tcx.def_path_str(key) }

compiler/rustc_mir/src/const_eval/fn_queries.rs

-6
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,11 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
151151
}
152152
}
153153

154-
fn const_fn_is_allowed_fn_ptr(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
155-
is_const_fn(tcx, def_id)
156-
&& tcx.lookup_const_stability(def_id).map(|stab| stab.allow_const_fn_ptr).unwrap_or(false)
157-
}
158-
159154
pub fn provide(providers: &mut Providers) {
160155
*providers = Providers {
161156
is_const_fn_raw,
162157
is_const_impl_raw: |tcx, def_id| is_const_impl_raw(tcx, def_id.expect_local()),
163158
is_promotable_const_fn,
164-
const_fn_is_allowed_fn_ptr,
165159
..*providers
166160
};
167161
}

compiler/rustc_mir/src/transform/check_consts/ops.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,21 @@ impl NonConstOp for FnPtrCast {
213213
const STOPS_CONST_CHECKING: bool = true;
214214

215215
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
216-
mcf_status_in_item(ccx)
216+
if ccx.const_kind() != hir::ConstContext::ConstFn {
217+
Status::Allowed
218+
} else {
219+
Status::Unstable(sym::const_fn_fn_ptr_basics)
220+
}
217221
}
218222

219223
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
220-
mcf_emit_error(ccx, span, "function pointer casts are not allowed in const fn");
224+
feature_err(
225+
&ccx.tcx.sess.parse_sess,
226+
sym::const_fn_fn_ptr_basics,
227+
span,
228+
&format!("function pointer casts are not allowed in {}s", ccx.const_kind()),
229+
)
230+
.emit()
221231
}
222232
}
223233

@@ -596,17 +606,21 @@ pub mod ty {
596606
const STOPS_CONST_CHECKING: bool = true;
597607

598608
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
599-
// FIXME: This attribute a hack to allow the specialization of the `futures` API. See
600-
// #59739. We should have a proper feature gate for this.
601-
if ccx.tcx.has_attr(ccx.def_id.to_def_id(), sym::rustc_allow_const_fn_ptr) {
609+
if ccx.const_kind() != hir::ConstContext::ConstFn {
602610
Status::Allowed
603611
} else {
604-
mcf_status_in_item(ccx)
612+
Status::Unstable(sym::const_fn_fn_ptr_basics)
605613
}
606614
}
607615

608616
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
609-
mcf_emit_error(ccx, span, "function pointers in const fn are unstable");
617+
feature_err(
618+
&ccx.tcx.sess.parse_sess,
619+
sym::const_fn_fn_ptr_basics,
620+
span,
621+
&format!("function pointers cannot appear in {}s", ccx.const_kind()),
622+
)
623+
.emit()
610624
}
611625
}
612626

compiler/rustc_span/src/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ symbols! {
353353
const_extern_fn,
354354
const_fn,
355355
const_fn_floating_point_arithmetic,
356+
const_fn_fn_ptr_basics,
356357
const_fn_transmute,
357358
const_fn_union,
358359
const_generics,
@@ -884,7 +885,6 @@ symbols! {
884885
rustc,
885886
rustc_allocator,
886887
rustc_allocator_nounwind,
887-
rustc_allow_const_fn_ptr,
888888
rustc_args_required_const,
889889
rustc_attrs,
890890
rustc_builtin_macro,

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
#![feature(const_fn_union)]
8484
#![feature(const_fn)]
8585
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
86+
#![cfg_attr(not(bootstrap), feature(const_fn_fn_ptr_basics))]
8687
#![feature(const_generics)]
8788
#![feature(const_option)]
8889
#![feature(const_precise_live_drops)]

library/core/src/task/wake.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,9 @@ impl RawWakerVTable {
129129
/// associated task.
130130
#[rustc_promotable]
131131
#[stable(feature = "futures_api", since = "1.36.0")]
132-
// `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
133-
// without first consulting with T-Lang.
134-
//
135-
// FIXME: remove whenever we have a stable way to accept fn pointers from const fn
136-
// (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
137-
#[rustc_allow_const_fn_ptr]
138132
#[rustc_const_stable(feature = "futures_api", since = "1.36.0")]
133+
#[cfg_attr(not(bootstrap), allow_internal_unstable(const_fn_fn_ptr_basics))]
134+
#[cfg_attr(bootstrap, rustc_allow_const_fn_ptr)]
139135
pub const fn new(
140136
clone: unsafe fn(*const ()) -> RawWaker,
141137
wake: unsafe fn(*const ()),

library/proc_macro/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#![feature(nll)]
2222
#![feature(staged_api)]
2323
#![feature(const_fn)]
24+
#![cfg_attr(not(bootstrap), feature(const_fn_fn_ptr_basics))]
2425
#![feature(allow_internal_unstable)]
2526
#![feature(decl_macro)]
2627
#![feature(extern_types)]

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@
239239
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
240240
#![feature(const_fn_transmute)]
241241
#![feature(const_fn)]
242+
#![cfg_attr(not(bootstrap), feature(const_fn_fn_ptr_basics))]
242243
#![feature(const_ip)]
243244
#![feature(const_ipv6)]
244245
#![feature(const_raw_ptr_deref)]

src/test/ui/consts/auxiliary/const_fn_lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Crate that exports a const fn. Used for testing cross-crate.
22

3-
#![feature(const_fn)]
3+
#![feature(const_fn_fn_ptr_basics)]
44
#![crate_type="rlib"]
55

66
pub const fn foo() -> usize { 22 }

src/test/ui/consts/const-eval/const_fn_ptr.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,23 @@ help: skipping check that does not even have a feature gate
1010
|
1111
LL | X_CONST(x)
1212
| ^^^^^^^^^^
13+
help: skipping check for `const_fn_fn_ptr_basics` feature
14+
--> $DIR/const_fn_ptr.rs:19:14
15+
|
16+
LL | const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
17+
| ^
18+
help: skipping check for `const_fn_fn_ptr_basics` feature
19+
--> $DIR/const_fn_ptr.rs:20:5
20+
|
21+
LL | x(y)
22+
| ^
1323
help: skipping check that does not even have a feature gate
1424
--> $DIR/const_fn_ptr.rs:20:5
1525
|
1626
LL | x(y)
1727
| ^^^^
1828

19-
warning: 1 warning emitted
29+
error: `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine
30+
31+
error: aborting due to previous error; 1 warning emitted
2032

src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ LL | assert_eq!(Z, 4);
2020

2121
warning: skipping const checks
2222
|
23+
help: skipping check for `const_fn_fn_ptr_basics` feature
24+
--> $DIR/const_fn_ptr_fail2.rs:12:14
25+
|
26+
LL | const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
27+
| ^
28+
help: skipping check for `const_fn_fn_ptr_basics` feature
29+
--> $DIR/const_fn_ptr_fail2.rs:13:5
30+
|
31+
LL | x(y)
32+
| ^
2333
help: skipping check that does not even have a feature gate
2434
--> $DIR/const_fn_ptr_fail2.rs:13:5
2535
|

src/test/ui/consts/const-eval/issue-70804-fn-subtyping.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// check-pass
2-
#![feature(const_fn)]
2+
#![feature(const_fn_fn_ptr_basics)]
33

44
const fn nested(x: (for<'a> fn(&'a ()), String)) -> (fn(&'static ()), String) {
55
x

src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
44
const unsafe extern "C" fn closure() -> fn() { || {} }
5-
//~^ ERROR function pointers in const fn are unstable
5+
//~^ ERROR function pointer
66
const unsafe extern fn use_float() { 1.0 + 1.0; }
77
//~^ ERROR floating point arithmetic
88
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }

src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0723]: function pointers in const fn are unstable
1+
error[E0658]: function pointers cannot appear in constant functions
22
--> $DIR/const-extern-fn-min-const-fn.rs:4:41
33
|
44
LL | const unsafe extern "C" fn closure() -> fn() { || {} }
55
| ^^^^
66
|
77
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
8-
= help: add `#![feature(const_fn)]` to the crate attributes to enable
8+
= help: add `#![feature(const_fn_fn_ptr_basics)]` to the crate attributes to enable
99

1010
error[E0658]: floating point arithmetic is not allowed in constant functions
1111
--> $DIR/const-extern-fn-min-const-fn.rs:6:38
@@ -27,5 +27,4 @@ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
2727

2828
error: aborting due to 3 previous errors
2929

30-
Some errors have detailed explanations: E0658, E0723.
31-
For more information about an error, try `rustc --explain E0658`.
30+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/consts/issue-37550.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#![allow(dead_code)]
33
#![allow(unused_variables)]
44

5-
#![feature(const_fn)]
5+
#![feature(const_fn_fn_ptr_basics)]
66

77
const fn x() {
88
let t = true;

src/test/ui/consts/issue-56164.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
#![feature(const_fn)]
1+
#![feature(const_fn_fn_ptr_basics)]
22

33
const fn foo() { (||{})() }
4-
//~^ ERROR calls in constant functions are limited to constant functions, tuple structs and tuple
5-
// variants
4+
//~^ ERROR calls in constant functions
65

76
const fn bad(input: fn()) {
87
input()
9-
//~^ ERROR function pointers are not allowed in const fn
8+
//~^ ERROR function pointer
109
}
1110

1211
fn main() {

src/test/ui/consts/issue-56164.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | const fn foo() { (||{})() }
55
| ^^^^^^^^
66

77
error: function pointers are not allowed in const fn
8-
--> $DIR/issue-56164.rs:8:5
8+
--> $DIR/issue-56164.rs:7:5
99
|
1010
LL | input()
1111
| ^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
#![feature(rustc_attrs, staged_api)]
1+
#![feature(rustc_attrs, staged_api, allow_internal_unstable)]
2+
#![feature(const_fn_fn_ptr_basics)]
23

34
#[stable(feature = "rust1", since = "1.0.0")]
45
#[rustc_const_stable(since="1.0.0", feature = "mep")]
5-
const fn error(_: fn()) {} //~ ERROR function pointers in const fn are unstable
6+
const fn error(_: fn()) {}
7+
//~^ ERROR const-stable function cannot use `#[feature(const_fn_fn_ptr_basics)]`
68

79
#[stable(feature = "rust1", since = "1.0.0")]
8-
#[rustc_allow_const_fn_ptr]
910
#[rustc_const_stable(since="1.0.0", feature = "mep")]
11+
#[allow_internal_unstable(const_fn_fn_ptr_basics)]
1012
const fn compiles(_: fn()) {}
1113

1214
fn main() {}

src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
error[E0723]: function pointers in const fn are unstable
2-
--> $DIR/allow_const_fn_ptr.rs:5:16
1+
error: const-stable function cannot use `#[feature(const_fn_fn_ptr_basics)]`
2+
--> $DIR/allow_const_fn_ptr.rs:6:16
33
|
44
LL | const fn error(_: fn()) {}
55
| ^
66
|
7-
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
8-
= help: add `#![feature(const_fn)]` to the crate attributes to enable
7+
= note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
8+
help: if it is not part of the public API, make this function unstably const
9+
|
10+
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
11+
|
912

1013
error: aborting due to previous error
1114

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

0 commit comments

Comments
 (0)