X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_ast_passes%2Fsrc%2Ffeature_gate.rs;h=5b2716b2dd088d405e9fd1b46356d3d488291968;hb=8035796b9aabf1aa2a711694e40f00fe8a822f40;hp=097bd07c74ce8a5ba6dca07e3f11d9bb113c423e;hpb=b711d17c374d7538c8f716cbeaf0fe8c6f7cd691;p=rust.git diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 097bd07c74c..5b2716b2dd0 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -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" @@ -252,17 +265,18 @@ fn check_abi(&self, abi: ast::StrLit) { "wasm ABI is experimental and subject to change" ); } - abi => self - .sess - .parse_sess - .span_diagnostic - .delay_span_bug(span, &format!("unrecognized ABI not caught in lowering: {}", abi)), + abi => { + self.sess.parse_sess.span_diagnostic.delay_span_bug( + span, + &format!("unrecognized ABI not caught in lowering: {}", abi), + ); + } } } - 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); } } @@ -444,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); } } @@ -567,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"); @@ -667,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() {