Stablize const_extern_fn
for "Rust" and "C"
All other ABIs are left unstable for now. cc #64926
This commit is contained in:
parent
1fca19c8ca
commit
8035796b9a
4 changed files with 42 additions and 69 deletions
|
@ -58,9 +58,22 @@ struct PostExpansionVisitor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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;
|
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() {
|
match symbol_unescaped.as_str() {
|
||||||
// Stable
|
// Stable
|
||||||
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
|
||||||
|
@ -261,9 +274,9 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_extern(&self, ext: ast::Extern) {
|
fn check_extern(&self, ext: ast::Extern, constness: ast::Const) {
|
||||||
if let ast::Extern::Explicit(abi) = ext {
|
if let ast::Extern::Explicit(abi) = ext {
|
||||||
self.check_abi(abi);
|
self.check_abi(abi, constness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +458,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
match i.kind {
|
match i.kind {
|
||||||
ast::ItemKind::ForeignMod(ref foreign_module) => {
|
ast::ItemKind::ForeignMod(ref foreign_module) => {
|
||||||
if let Some(abi) = foreign_module.abi {
|
if let Some(abi) = foreign_module.abi {
|
||||||
self.check_abi(abi);
|
self.check_abi(abi, ast::Const::No);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +581,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
ast::TyKind::BareFn(ref bare_fn_ty) => {
|
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 => {
|
ast::TyKind::Never => {
|
||||||
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
|
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
|
||||||
|
@ -668,18 +682,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
||||||
if let Some(header) = fn_kind.header() {
|
if let Some(header) = fn_kind.header() {
|
||||||
// Stability of const fn methods are covered in `visit_assoc_item` below.
|
// Stability of const fn methods are covered in `visit_assoc_item` below.
|
||||||
self.check_extern(header.ext);
|
self.check_extern(header.ext, header.constness);
|
||||||
|
|
||||||
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"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
|
if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
|
||||||
|
|
|
@ -523,6 +523,9 @@ impl<'a> Parser<'a> {
|
||||||
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
|
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
|
||||||
let whole_span = lo.to(self.prev_token.span);
|
let whole_span = lo.to(self.prev_token.span);
|
||||||
if let ast::Const::Yes(span) = constness {
|
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");
|
self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
|
||||||
}
|
}
|
||||||
if let ast::Async::Yes { span, .. } = asyncness {
|
if let ast::Async::Yes { span, .. } = asyncness {
|
||||||
|
|
|
@ -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 fn foo1() {}
|
||||||
const extern "C" fn foo2() {} //~ ERROR `const extern fn` definitions are unstable
|
const extern "C" fn foo2() {}
|
||||||
const extern "Rust" fn foo3() {} //~ ERROR `const extern fn` definitions are unstable
|
const extern "Rust" fn foo3() {}
|
||||||
const unsafe extern fn bar1() {} //~ ERROR `const extern fn` definitions are unstable
|
const extern "cdecl" fn foo4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
|
||||||
const unsafe extern "C" fn bar2() {} //~ ERROR `const extern fn` definitions are unstable
|
const unsafe extern fn bar1() {}
|
||||||
const unsafe extern "Rust" fn bar3() {} //~ ERROR `const extern fn` definitions are unstable
|
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() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,57 +1,21 @@
|
||||||
error[E0658]: `const extern fn` definitions are unstable
|
error[E0658]: `cdecl` as a `const fn` ABI is unstable
|
||||||
--> $DIR/feature-gate-const_extern_fn.rs:3:1
|
--> $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
|
= 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
|
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `const extern fn` definitions are unstable
|
error[E0658]: `cdecl` as a `const fn` ABI is unstable
|
||||||
--> $DIR/feature-gate-const_extern_fn.rs:4:1
|
--> $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
|
= 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
|
= help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `const extern fn` definitions are unstable
|
error: aborting due to 2 previous errors
|
||||||
--> $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
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue