Skip to content

Commit 869c3bb

Browse files
authored
Rollup merge of rust-lang#95346 - Aaron1011:stablize-const-extern-fn, r=pnkfelix
Stablize `const_extern_fn` for "Rust" and "C" All other ABIs are left unstable for now. cc rust-lang#64926
2 parents 15c0e29 + 8035796 commit 869c3bb

File tree

4 files changed

+42
-69
lines changed

4 files changed

+42
-69
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,22 @@ struct PostExpansionVisitor<'a> {
5858
}
5959

6060
impl<'a> PostExpansionVisitor<'a> {
61-
fn check_abi(&self, abi: ast::StrLit) {
61+
fn check_abi(&self, abi: ast::StrLit, constness: ast::Const) {
6262
let ast::StrLit { symbol_unescaped, span, .. } = abi;
6363

64+
if let ast::Const::Yes(_) = constness {
65+
match symbol_unescaped.as_str() {
66+
// Stable
67+
"Rust" | "C" => {}
68+
abi => gate_feature_post!(
69+
&self,
70+
const_extern_fn,
71+
span,
72+
&format!("`{}` as a `const fn` ABI is unstable", abi)
73+
),
74+
}
75+
}
76+
6477
match symbol_unescaped.as_str() {
6578
// Stable
6679
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
@@ -261,9 +274,9 @@ impl<'a> PostExpansionVisitor<'a> {
261274
}
262275
}
263276

264-
fn check_extern(&self, ext: ast::Extern) {
277+
fn check_extern(&self, ext: ast::Extern, constness: ast::Const) {
265278
if let ast::Extern::Explicit(abi) = ext {
266-
self.check_abi(abi);
279+
self.check_abi(abi, constness);
267280
}
268281
}
269282

@@ -437,7 +450,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
437450
match i.kind {
438451
ast::ItemKind::ForeignMod(ref foreign_module) => {
439452
if let Some(abi) = foreign_module.abi {
440-
self.check_abi(abi);
453+
self.check_abi(abi, ast::Const::No);
441454
}
442455
}
443456

@@ -560,7 +573,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
560573
fn visit_ty(&mut self, ty: &'a ast::Ty) {
561574
match ty.kind {
562575
ast::TyKind::BareFn(ref bare_fn_ty) => {
563-
self.check_extern(bare_fn_ty.ext);
576+
// Function pointers cannot be `const`
577+
self.check_extern(bare_fn_ty.ext, ast::Const::No);
564578
}
565579
ast::TyKind::Never => {
566580
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
@@ -660,18 +674,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
660674
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
661675
if let Some(header) = fn_kind.header() {
662676
// Stability of const fn methods are covered in `visit_assoc_item` below.
663-
self.check_extern(header.ext);
664-
665-
if let (ast::Const::Yes(_), ast::Extern::Implicit)
666-
| (ast::Const::Yes(_), ast::Extern::Explicit(_)) = (header.constness, header.ext)
667-
{
668-
gate_feature_post!(
669-
&self,
670-
const_extern_fn,
671-
span,
672-
"`const extern fn` definitions are unstable"
673-
);
674-
}
677+
self.check_extern(header.ext, header.constness);
675678
}
676679

677680
if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {

compiler/rustc_parse/src/parser/ty.rs

+3
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,9 @@ impl<'a> Parser<'a> {
523523
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
524524
let whole_span = lo.to(self.prev_token.span);
525525
if let ast::Const::Yes(span) = constness {
526+
// If we ever start to allow `const fn()`, then update
527+
// feature gating for `#![feature(const_extern_fn)]` to
528+
// cover it.
526529
self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
527530
}
528531
if let ast::Async::Yes { span, .. } = asyncness {
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
// Check that `const extern fn` and `const unsafe extern fn` are feature-gated.
1+
// Check that `const extern fn` and `const unsafe extern fn` are feature-gated
2+
// for certain ABIs.
23

3-
const extern fn foo1() {} //~ ERROR `const extern fn` definitions are unstable
4-
const extern "C" fn foo2() {} //~ ERROR `const extern fn` definitions are unstable
5-
const extern "Rust" fn foo3() {} //~ ERROR `const extern fn` definitions are unstable
6-
const unsafe extern fn bar1() {} //~ ERROR `const extern fn` definitions are unstable
7-
const unsafe extern "C" fn bar2() {} //~ ERROR `const extern fn` definitions are unstable
8-
const unsafe extern "Rust" fn bar3() {} //~ ERROR `const extern fn` definitions are unstable
4+
const extern fn foo1() {}
5+
const extern "C" fn foo2() {}
6+
const extern "Rust" fn foo3() {}
7+
const extern "cdecl" fn foo4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
8+
const unsafe extern fn bar1() {}
9+
const unsafe extern "C" fn bar2() {}
10+
const unsafe extern "Rust" fn bar3() {}
11+
const unsafe extern "cdecl" fn bar4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
912

1013
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,21 @@
1-
error[E0658]: `const extern fn` definitions are unstable
2-
--> $DIR/feature-gate-const_extern_fn.rs:3:1
1+
error[E0658]: `cdecl` as a `const fn` ABI is unstable
2+
--> $DIR/feature-gate-const_extern_fn.rs:7:14
33
|
4-
LL | const extern fn foo1() {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | const extern "cdecl" fn foo4() {}
5+
| ^^^^^^^
66
|
77
= note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
88
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
99

10-
error[E0658]: `const extern fn` definitions are unstable
11-
--> $DIR/feature-gate-const_extern_fn.rs:4:1
10+
error[E0658]: `cdecl` as a `const fn` ABI is unstable
11+
--> $DIR/feature-gate-const_extern_fn.rs:11:21
1212
|
13-
LL | const extern "C" fn foo2() {}
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
LL | const unsafe extern "cdecl" fn bar4() {}
14+
| ^^^^^^^
1515
|
1616
= note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
1717
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
1818

19-
error[E0658]: `const extern fn` definitions are unstable
20-
--> $DIR/feature-gate-const_extern_fn.rs:5:1
21-
|
22-
LL | const extern "Rust" fn foo3() {}
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24-
|
25-
= note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
26-
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
27-
28-
error[E0658]: `const extern fn` definitions are unstable
29-
--> $DIR/feature-gate-const_extern_fn.rs:6:1
30-
|
31-
LL | const unsafe extern fn bar1() {}
32-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33-
|
34-
= note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
35-
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
36-
37-
error[E0658]: `const extern fn` definitions are unstable
38-
--> $DIR/feature-gate-const_extern_fn.rs:7:1
39-
|
40-
LL | const unsafe extern "C" fn bar2() {}
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42-
|
43-
= note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
44-
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
45-
46-
error[E0658]: `const extern fn` definitions are unstable
47-
--> $DIR/feature-gate-const_extern_fn.rs:8:1
48-
|
49-
LL | const unsafe extern "Rust" fn bar3() {}
50-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51-
|
52-
= note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
53-
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
54-
55-
error: aborting due to 6 previous errors
19+
error: aborting due to 2 previous errors
5620

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

0 commit comments

Comments
 (0)