1
Fork 0

Stablize const_extern_fn for "Rust" and "C"

All other ABIs are left unstable for now.

cc #64926
This commit is contained in:
Aaron Hill 2022-03-26 18:23:32 -04:00
parent 1fca19c8ca
commit 8035796b9a
No known key found for this signature in database
GPG key ID: B4087E510E98B164
4 changed files with 42 additions and 69 deletions

View 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 @@ 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 {
self.check_abi(abi);
self.check_abi(abi, constness);
}
}
@ -445,7 +458,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
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 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
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() {