]> git.lizzy.rs Git - rust.git/commitdiff
Stablize `const_extern_fn` for "Rust" and "C"
authorAaron Hill <aa1ronham@gmail.com>
Sat, 26 Mar 2022 22:23:32 +0000 (18:23 -0400)
committerAaron Hill <aa1ronham@gmail.com>
Sat, 26 Mar 2022 22:23:54 +0000 (18:23 -0400)
All other ABIs are left unstable for now.

cc #64926

compiler/rustc_ast_passes/src/feature_gate.rs
compiler/rustc_parse/src/parser/ty.rs
src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs
src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr

index 5b6147c72230d53b943586280b3a6d457d103886..5b2716b2dd088d405e9fd1b46356d3d488291968 100644 (file)
@@ -58,9 +58,22 @@ struct PostExpansionVisitor<'a> {
 }
 
 impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: ast::StrLit) {
+    fn check_abi(&self, abi: ast::StrLit, constness: ast::Const) {
         let ast::StrLit { symbol_unescaped, span, .. } = abi;
 
+        if let ast::Const::Yes(_) = constness {
+            match symbol_unescaped.as_str() {
+                // Stable
+                "Rust" | "C" => {}
+                abi => gate_feature_post!(
+                    &self,
+                    const_extern_fn,
+                    span,
+                    &format!("`{}` as a `const fn` ABI is unstable", abi)
+                ),
+            }
+        }
+
         match symbol_unescaped.as_str() {
             // Stable
             "Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
@@ -261,9 +274,9 @@ fn check_abi(&self, abi: ast::StrLit) {
         }
     }
 
-    fn check_extern(&self, ext: ast::Extern) {
+    fn check_extern(&self, ext: ast::Extern, constness: ast::Const) {
         if let ast::Extern::Explicit(abi) = ext {
-            self.check_abi(abi);
+            self.check_abi(abi, constness);
         }
     }
 
@@ -445,7 +458,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
         match i.kind {
             ast::ItemKind::ForeignMod(ref foreign_module) => {
                 if let Some(abi) = foreign_module.abi {
-                    self.check_abi(abi);
+                    self.check_abi(abi, ast::Const::No);
                 }
             }
 
@@ -568,7 +581,8 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
         match ty.kind {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_extern(bare_fn_ty.ext);
+                // Function pointers cannot be `const`
+                self.check_extern(bare_fn_ty.ext, ast::Const::No);
             }
             ast::TyKind::Never => {
                 gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
@@ -668,18 +682,7 @@ fn visit_pat(&mut self, pattern: &'a ast::Pat) {
     fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
         if let Some(header) = fn_kind.header() {
             // Stability of const fn methods are covered in `visit_assoc_item` below.
-            self.check_extern(header.ext);
-
-            if let (ast::Const::Yes(_), ast::Extern::Implicit)
-            | (ast::Const::Yes(_), ast::Extern::Explicit(_)) = (header.constness, header.ext)
-            {
-                gate_feature_post!(
-                    &self,
-                    const_extern_fn,
-                    span,
-                    "`const extern fn` definitions are unstable"
-                );
-            }
+            self.check_extern(header.ext, header.constness);
         }
 
         if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
index 436c5bd4fcac23fc7b62f5f305d0442530613c21..bb387064e27fe0e583c16f63a565cf8e96d94383 100644 (file)
@@ -523,6 +523,9 @@ fn parse_ty_bare_fn(
         let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
         let whole_span = lo.to(self.prev_token.span);
         if let ast::Const::Yes(span) = constness {
+            // If we ever start to allow `const fn()`, then update
+            // feature gating for `#![feature(const_extern_fn)]` to
+            // cover it.
             self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
         }
         if let ast::Async::Yes { span, .. } = asyncness {
index 5667d5535274d161c5b38bf434638d6ba476a006..f7bed91b03787bd899c01c2189ae16f28f7e31e1 100644 (file)
@@ -1,10 +1,13 @@
-// Check that `const extern fn` and `const unsafe extern fn` are feature-gated.
+// Check that `const extern fn` and `const unsafe extern fn` are feature-gated
+// for certain ABIs.
 
-const extern fn foo1() {} //~ ERROR `const extern fn` definitions are unstable
-const extern "C" fn foo2() {} //~ ERROR `const extern fn` definitions are unstable
-const extern "Rust" fn foo3() {} //~ ERROR `const extern fn` definitions are unstable
-const unsafe extern fn bar1() {} //~ ERROR `const extern fn` definitions are unstable
-const unsafe extern "C" fn bar2() {} //~ ERROR `const extern fn` definitions are unstable
-const unsafe extern "Rust" fn bar3() {} //~ ERROR `const extern fn` definitions are unstable
+const extern fn foo1() {}
+const extern "C" fn foo2() {}
+const extern "Rust" fn foo3() {}
+const extern "cdecl" fn foo4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
+const unsafe extern fn bar1() {}
+const unsafe extern "C" fn bar2() {}
+const unsafe extern "Rust" fn bar3() {}
+const unsafe extern "cdecl" fn bar4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
 
 fn main() {}
index bd5940a3fd60c17cf07a67b5fd6512c8ba149309..f8c3107bd221aa40b2f56682e3a871748b60ecb0 100644 (file)
@@ -1,57 +1,21 @@
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:3:1
+error[E0658]: `cdecl` as a `const fn` ABI is unstable
+  --> $DIR/feature-gate-const_extern_fn.rs:7:14
    |
-LL | const extern fn foo1() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const extern "cdecl" fn foo4() {}
+   |              ^^^^^^^
    |
    = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
    = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
 
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:4:1
+error[E0658]: `cdecl` as a `const fn` ABI is unstable
+  --> $DIR/feature-gate-const_extern_fn.rs:11:21
    |
-LL | const extern "C" fn foo2() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const unsafe extern "cdecl" fn bar4() {}
+   |                     ^^^^^^^
    |
    = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
    = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
 
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:5:1
-   |
-LL | const extern "Rust" fn foo3() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:6:1
-   |
-LL | const unsafe extern fn bar1() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:7:1
-   |
-LL | const unsafe extern "C" fn bar2() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:8:1
-   |
-LL | const unsafe extern "Rust" fn bar3() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.