Skip to content

Commit a24de0c

Browse files
authored
Rollup merge of rust-lang#34904 - petrochenkov:rustcall, r=nikomatsakis
Properly feature gate all unstable ABIs Fixes rust-lang#34900 [breaking-change] r? @pnkfelix --- Function-visiting machinery for AST/HIR is surprisingly error-prone, it's *very* easy to miss some cases or visit something twice while writing a visitor. This is the true problem behind rust-lang#34900. I'll try to restructure these visitors a bit and send one more PR later.
2 parents 5a7773a + 9292c0b commit a24de0c

File tree

6 files changed

+103
-73
lines changed

6 files changed

+103
-73
lines changed

src/doc/book/closures.md

+1
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ trait system to overload operators. Calling functions is no different. We have
223223
three separate traits to overload with:
224224

225225
```rust
226+
# #![feature(unboxed_closures)]
226227
# mod foo {
227228
pub trait Fn<Args> : FnMut<Args> {
228229
extern "rust-call" fn call(&self, args: Args) -> Self::Output;

src/libsyntax/feature_gate.rs

+41-32
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,29 @@ macro_rules! gate_feature_post {
810810
}}
811811
}
812812

813+
impl<'a> PostExpansionVisitor<'a> {
814+
fn check_abi(&self, abi: Abi, span: Span) {
815+
match abi {
816+
Abi::RustIntrinsic =>
817+
gate_feature_post!(&self, intrinsics, span,
818+
"intrinsics are subject to change"),
819+
Abi::PlatformIntrinsic => {
820+
gate_feature_post!(&self, platform_intrinsics, span,
821+
"platform intrinsics are experimental and possibly buggy")
822+
},
823+
Abi::Vectorcall => {
824+
gate_feature_post!(&self, abi_vectorcall, span,
825+
"vectorcall is experimental and subject to change")
826+
}
827+
Abi::RustCall => {
828+
gate_feature_post!(&self, unboxed_closures, span,
829+
"rust-call ABI is subject to change");
830+
}
831+
_ => {}
832+
}
833+
}
834+
}
835+
813836
impl<'a> Visitor for PostExpansionVisitor<'a> {
814837
fn visit_attribute(&mut self, attr: &ast::Attribute) {
815838
if !self.context.cm.span_allows_unstable(attr.span) {
@@ -841,21 +864,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
841864
across platforms, it is recommended to \
842865
use `#[link(name = \"foo\")]` instead")
843866
}
844-
match foreign_module.abi {
845-
Abi::RustIntrinsic =>
846-
gate_feature_post!(&self, intrinsics, i.span,
847-
"intrinsics are subject to change"),
848-
Abi::PlatformIntrinsic => {
849-
gate_feature_post!(&self, platform_intrinsics, i.span,
850-
"platform intrinsics are experimental \
851-
and possibly buggy")
852-
},
853-
Abi::Vectorcall => {
854-
gate_feature_post!(&self, abi_vectorcall, i.span,
855-
"vectorcall is experimental and subject to change")
856-
}
857-
_ => ()
858-
}
867+
self.check_abi(foreign_module.abi, i.span);
859868
}
860869

861870
ast::ItemKind::Fn(..) => {
@@ -938,6 +947,16 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
938947
visit::walk_foreign_item(self, i)
939948
}
940949

950+
fn visit_ty(&mut self, ty: &ast::Ty) {
951+
match ty.node {
952+
ast::TyKind::BareFn(ref bare_fn_ty) => {
953+
self.check_abi(bare_fn_ty.abi, ty.span);
954+
}
955+
_ => {}
956+
}
957+
visit::walk_ty(self, ty)
958+
}
959+
941960
fn visit_expr(&mut self, e: &ast::Expr) {
942961
match e.node {
943962
ast::ExprKind::Box(_) => {
@@ -1025,23 +1044,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
10251044
}
10261045

10271046
match fn_kind {
1028-
FnKind::ItemFn(_, _, _, _, abi, _) if abi == Abi::RustIntrinsic => {
1029-
gate_feature_post!(&self, intrinsics,
1030-
span,
1031-
"intrinsics are subject to change")
1032-
}
10331047
FnKind::ItemFn(_, _, _, _, abi, _) |
1034-
FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => match abi {
1035-
Abi::RustCall => {
1036-
gate_feature_post!(&self, unboxed_closures, span,
1037-
"rust-call ABI is subject to change");
1038-
},
1039-
Abi::Vectorcall => {
1040-
gate_feature_post!(&self, abi_vectorcall, span,
1041-
"vectorcall is experimental and subject to change");
1042-
},
1043-
_ => {}
1044-
},
1048+
FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => {
1049+
self.check_abi(abi, span);
1050+
}
10451051
_ => {}
10461052
}
10471053
visit::walk_fn(self, fn_kind, fn_decl, block, span);
@@ -1054,7 +1060,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
10541060
ti.span,
10551061
"associated constants are experimental")
10561062
}
1057-
ast::TraitItemKind::Method(ref sig, _) => {
1063+
ast::TraitItemKind::Method(ref sig, ref block) => {
1064+
if block.is_none() {
1065+
self.check_abi(sig.abi, ti.span);
1066+
}
10581067
if sig.constness == ast::Constness::Const {
10591068
gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
10601069
}

src/test/compile-fail/E0045.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
extern "rust-call" { fn foo(x: u8, ...); } //~ ERROR E0045
11+
extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045
1212

1313
fn main() {
1414
}

src/test/compile-fail/feature-gate-abi-vectorcall.rs

-19
This file was deleted.
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Functions
12+
extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
13+
extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
14+
extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change
15+
extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change
16+
17+
// Methods in trait definition
18+
trait Tr {
19+
extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change
20+
extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
21+
extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change
22+
extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change
23+
24+
extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change
25+
extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental
26+
extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change
27+
extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change
28+
}
29+
30+
struct S;
31+
32+
// Methods in trait impl
33+
impl Tr for S {
34+
extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change
35+
extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
36+
extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change
37+
extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change
38+
}
39+
40+
// Methods in inherent impl
41+
impl S {
42+
extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change
43+
extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
44+
extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change
45+
extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change
46+
}
47+
48+
// Function pointer types
49+
type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
50+
type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental
51+
type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change
52+
type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change
53+
54+
// Foreign modules
55+
extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
56+
extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental
57+
extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to change
58+
extern "rust-call" {} //~ ERROR rust-call ABI is subject to change
59+
60+
fn main() {}

src/test/compile-fail/feature-gate-rust-call.rs

-21
This file was deleted.

0 commit comments

Comments
 (0)