Skip to content

Commit 027a557

Browse files
committed
stabilize const_extern_fn
1 parent 02b1be1 commit 027a557

26 files changed

+86
-133
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+6-19
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,9 @@ struct PostExpansionVisitor<'a> {
7575

7676
impl<'a> PostExpansionVisitor<'a> {
7777
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
78-
fn check_abi(&self, abi: ast::StrLit, constness: ast::Const) {
78+
fn check_abi(&self, abi: ast::StrLit) {
7979
let ast::StrLit { symbol_unescaped, span, .. } = abi;
8080

81-
if let ast::Const::Yes(_) = constness {
82-
match symbol_unescaped {
83-
// Stable
84-
sym::Rust | sym::C => {}
85-
abi => gate!(
86-
&self,
87-
const_extern_fn,
88-
span,
89-
format!("`{}` as a `const fn` ABI is unstable", abi)
90-
),
91-
}
92-
}
93-
9481
match abi::is_enabled(self.features, span, symbol_unescaped.as_str()) {
9582
Ok(()) => (),
9683
Err(abi::AbiDisabled::Unstable { feature, explain }) => {
@@ -110,9 +97,9 @@ impl<'a> PostExpansionVisitor<'a> {
11097
}
11198
}
11299

113-
fn check_extern(&self, ext: ast::Extern, constness: ast::Const) {
100+
fn check_extern(&self, ext: ast::Extern) {
114101
if let ast::Extern::Explicit(abi, _) = ext {
115-
self.check_abi(abi, constness);
102+
self.check_abi(abi);
116103
}
117104
}
118105

@@ -239,7 +226,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
239226
match &i.kind {
240227
ast::ItemKind::ForeignMod(foreign_module) => {
241228
if let Some(abi) = foreign_module.abi {
242-
self.check_abi(abi, ast::Const::No);
229+
self.check_abi(abi);
243230
}
244231
}
245232

@@ -341,7 +328,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
341328
match &ty.kind {
342329
ast::TyKind::BareFn(bare_fn_ty) => {
343330
// Function pointers cannot be `const`
344-
self.check_extern(bare_fn_ty.ext, ast::Const::No);
331+
self.check_extern(bare_fn_ty.ext);
345332
self.check_late_bound_lifetime_defs(&bare_fn_ty.generic_params);
346333
}
347334
ast::TyKind::Never => {
@@ -446,7 +433,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
446433
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
447434
if let Some(header) = fn_kind.header() {
448435
// Stability of const fn methods are covered in `visit_assoc_item` below.
449-
self.check_extern(header.ext, header.constness);
436+
self.check_extern(header.ext);
450437
}
451438

452439
if let FnKind::Closure(ast::ClosureBinder::For { generic_params, .. }, ..) = fn_kind {

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ declare_features! (
115115
(accepted, conservative_impl_trait, "1.26.0", Some(34511)),
116116
/// Allows calling constructor functions in `const fn`.
117117
(accepted, const_constructor, "1.40.0", Some(61456)),
118+
/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
119+
(accepted, const_extern_fn, "CURRENT_RUSTC_VERSION", Some(64926)),
118120
/// Allows basic arithmetic on floating point types in a `const fn`.
119121
(accepted, const_fn_floating_point_arithmetic, "1.82.0", Some(57241)),
120122
/// Allows using and casting function pointers in a `const fn`.

compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,6 @@ declare_features! (
401401
(unstable, const_async_blocks, "1.53.0", Some(85368)),
402402
/// Allows `const || {}` closures in const contexts.
403403
(incomplete, const_closures, "1.68.0", Some(106003)),
404-
/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
405-
(unstable, const_extern_fn, "1.40.0", Some(64926)),
406404
/// Allows `for _ in _` loops in const contexts.
407405
(unstable, const_for, "1.56.0", Some(87575)),
408406
/// Allows using `&mut` in constant functions.

compiler/rustc_parse/src/parser/ty.rs

-3
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,6 @@ impl<'a> Parser<'a> {
607607
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
608608
let whole_span = lo.to(self.prev_token.span);
609609
if let ast::Const::Yes(span) = constness {
610-
// If we ever start to allow `const fn()`, then update
611-
// feature gating for `#![feature(const_extern_fn)]` to
612-
// cover it.
613610
self.dcx().emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
614611
}
615612
if let Some(ast::CoroutineKind::Async { span, .. }) = coroutine_kind {

src/tools/clippy/clippy_config/src/msrvs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ macro_rules! msrv_aliases {
1717

1818
// names may refer to stabilized feature flags or library items
1919
msrv_aliases! {
20+
1,83,0 { CONST_EXTERN_FN }
2021
1,83,0 { CONST_FLOAT_BITS_CONV }
2122
1,81,0 { LINT_REASONS_STABILIZATION }
2223
1,80,0 { BOX_INTO_ITER}
@@ -27,7 +28,7 @@ msrv_aliases! {
2728
1,68,0 { PATH_MAIN_SEPARATOR_STR }
2829
1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
2930
1,63,0 { CLONE_INTO }
30-
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_FN }
31+
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN }
3132
1,59,0 { THREAD_LOCAL_CONST_INIT }
3233
1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF }
3334
1,56,0 { CONST_FN_UNION }

src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
119119
.iter()
120120
.any(|param| matches!(param.kind, GenericParamKind::Const { .. }));
121121

122-
if already_const(header)
123-
|| has_const_generic_params
124-
|| !could_be_const_with_abi(cx, &self.msrv, header.abi)
122+
if already_const(header) || has_const_generic_params || !could_be_const_with_abi(&self.msrv, header.abi)
125123
{
126124
return;
127125
}
@@ -183,13 +181,13 @@ fn already_const(header: hir::FnHeader) -> bool {
183181
header.constness == Constness::Const
184182
}
185183

186-
fn could_be_const_with_abi(cx: &LateContext<'_>, msrv: &Msrv, abi: Abi) -> bool {
184+
fn could_be_const_with_abi(msrv: &Msrv, abi: Abi) -> bool {
187185
match abi {
188186
Abi::Rust => true,
189187
// `const extern "C"` was stabilized after 1.62.0
190-
Abi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_FN),
188+
Abi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN),
191189
// Rest ABIs are still unstable and need the `const_extern_fn` feature enabled.
192-
_ => cx.tcx.features().const_extern_fn,
190+
_ => msrv.meets(msrvs::CONST_EXTERN_FN),
193191
}
194192
}
195193

src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs

-6
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,6 @@ mod msrv {
186186
extern "C" fn c() {}
187187
}
188188

189-
mod with_extern {
190-
extern "C-unwind" fn c_unwind() {}
191-
extern "system" fn system() {}
192-
extern "system-unwind" fn system_unwind() {}
193-
}
194-
195189
mod with_ty_alias {
196190
type Foo = impl std::fmt::Debug;
197191

src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.fixed

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![warn(clippy::missing_const_for_fn)]
22
#![allow(unsupported_calling_conventions)]
3-
#![feature(const_extern_fn)]
43

54
const extern "C-unwind" fn c_unwind() {}
65
//~^ ERROR: this could be a `const fn`

src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![warn(clippy::missing_const_for_fn)]
22
#![allow(unsupported_calling_conventions)]
3-
#![feature(const_extern_fn)]
43

54
extern "C-unwind" fn c_unwind() {}
65
//~^ ERROR: this could be a `const fn`

src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this could be a `const fn`
2-
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:5:1
2+
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:4:1
33
|
44
LL | extern "C-unwind" fn c_unwind() {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -12,7 +12,7 @@ LL | const extern "C-unwind" fn c_unwind() {}
1212
| +++++
1313

1414
error: this could be a `const fn`
15-
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:7:1
15+
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:6:1
1616
|
1717
LL | extern "system" fn system() {}
1818
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | const extern "system" fn system() {}
2323
| +++++
2424

2525
error: this could be a `const fn`
26-
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:9:1
26+
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:8:1
2727
|
2828
LL | extern "system-unwind" fn system_unwind() {}
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ LL | const extern "system-unwind" fn system_unwind() {}
3434
| +++++
3535

3636
error: this could be a `const fn`
37-
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:11:1
37+
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:10:1
3838
|
3939
LL | pub extern "stdcall" fn std_call() {}
4040
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL | pub const extern "stdcall" fn std_call() {}
4545
| +++++
4646

4747
error: this could be a `const fn`
48-
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:13:1
48+
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:12:1
4949
|
5050
LL | pub extern "stdcall-unwind" fn std_call_unwind() {}
5151
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui/consts/const-eval/unwind-abort.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_extern_fn)]
2-
31
const extern "C" fn foo() {
42
panic!() //~ ERROR evaluation of constant value failed
53
}

tests/ui/consts/const-eval/unwind-abort.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/unwind-abort.rs:4:5
2+
--> $DIR/unwind-abort.rs:2:5
33
|
44
LL | panic!()
5-
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:4:5
5+
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:2:5
66
|
77
note: inside `foo`
8-
--> $DIR/unwind-abort.rs:4:5
8+
--> $DIR/unwind-abort.rs:2:5
99
|
1010
LL | panic!()
1111
| ^^^^^^^^
1212
note: inside `_`
13-
--> $DIR/unwind-abort.rs:7:15
13+
--> $DIR/unwind-abort.rs:5:15
1414
|
1515
LL | const _: () = foo();
1616
| ^^^^^

tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_extern_fn)]
2-
31
extern "C" {
42
fn regular_in_block();
53
}

tests/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0015]: cannot call non-const fn `regular_in_block` in constant functions
2-
--> $DIR/const-extern-fn-call-extern-fn.rs:9:9
2+
--> $DIR/const-extern-fn-call-extern-fn.rs:7:9
33
|
44
LL | regular_in_block();
55
| ^^^^^^^^^^^^^^^^^^
66
|
77
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
88

99
error[E0015]: cannot call non-const fn `regular` in constant functions
10-
--> $DIR/const-extern-fn-call-extern-fn.rs:18:9
10+
--> $DIR/const-extern-fn-call-extern-fn.rs:16:9
1111
|
1212
LL | regular();
1313
| ^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
#![feature(const_extern_fn)]
2-
3-
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
4-
//~^ ERROR pointers cannot be cast to integers
5-
1+
const extern "C" fn ptr_cast(val: *const u8) {
2+
val as usize;
3+
//~^ ERROR pointers cannot be cast to integers
4+
}
65

76
fn main() {}

tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: pointers cannot be cast to integers during const eval
2-
--> $DIR/const-extern-fn-min-const-fn.rs:3:48
2+
--> $DIR/const-extern-fn-min-const-fn.rs:2:5
33
|
4-
LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
5-
| ^^^^^^^^^^^^
4+
LL | val as usize;
5+
| ^^^^^^^^^^^^
66
|
77
= note: at compile-time, pointers do not have an integer value
88
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
#![feature(const_extern_fn)]
2-
31
const unsafe extern "C" fn foo() -> usize {
42
5
53
}
64

5+
const unsafe extern "C-unwind" fn bar() -> usize {
6+
5
7+
}
8+
79
fn main() {
810
let a: [u8; foo()];
911
//~^ call to unsafe function `foo` is unsafe and requires unsafe function or block
1012
foo();
1113
//~^ ERROR call to unsafe function `foo` is unsafe and requires unsafe function or block
14+
let b: [u8; bar()];
15+
//~^ call to unsafe function `bar` is unsafe and requires unsafe function or block
16+
bar();
17+
//~^ ERROR call to unsafe function `bar` is unsafe and requires unsafe function or block
1218
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
2-
--> $DIR/const-extern-fn-requires-unsafe.rs:10:5
2+
--> $DIR/const-extern-fn-requires-unsafe.rs:12:5
33
|
44
LL | foo();
55
| ^^^^^ call to unsafe function
66
|
77
= note: consult the function's documentation for information on how to avoid undefined behavior
88

9+
error[E0133]: call to unsafe function `bar` is unsafe and requires unsafe function or block
10+
--> $DIR/const-extern-fn-requires-unsafe.rs:16:5
11+
|
12+
LL | bar();
13+
| ^^^^^ call to unsafe function
14+
|
15+
= note: consult the function's documentation for information on how to avoid undefined behavior
16+
917
error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
10-
--> $DIR/const-extern-fn-requires-unsafe.rs:8:17
18+
--> $DIR/const-extern-fn-requires-unsafe.rs:10:17
1119
|
1220
LL | let a: [u8; foo()];
1321
| ^^^^^ call to unsafe function
1422
|
1523
= note: consult the function's documentation for information on how to avoid undefined behavior
1624

17-
error: aborting due to 2 previous errors
25+
error[E0133]: call to unsafe function `bar` is unsafe and requires unsafe function or block
26+
--> $DIR/const-extern-fn-requires-unsafe.rs:14:17
27+
|
28+
LL | let b: [u8; bar()];
29+
| ^^^^^ call to unsafe function
30+
|
31+
= note: consult the function's documentation for information on how to avoid undefined behavior
32+
33+
error: aborting due to 4 previous errors
1834

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

tests/ui/consts/const-extern-fn/const-extern-fn.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//@ run-pass
2-
#![feature(const_extern_fn)]
32

43
const extern "C" fn foo1(val: u8) -> u8 {
54
val + 1
@@ -47,6 +46,10 @@ fn main() {
4746
let _bar2_cast: unsafe extern "C" fn(bool) -> bool = bar2;
4847

4948
unsize(&[0, 1, 2]);
50-
unsafe { closure(); }
51-
unsafe { use_float(); }
49+
unsafe {
50+
closure();
51+
}
52+
unsafe {
53+
use_float();
54+
}
5255
}

tests/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs

-13
This file was deleted.

tests/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr

-23
This file was deleted.

0 commit comments

Comments
 (0)