Skip to content

Commit 611360f

Browse files
authored
Rollup merge of #103239 - m-ou-se:unstable-abi-fn-impl-check, r=lcnr
Allow #[unstable] impls for fn() with unstable abi. This allows `#[unstable]` trait impls for `extern "unwind-C" fn()`, based on the fact that that abi and therefore that type is unstable. See #101263 (comment)
2 parents ddcdd28 + c4f829b commit 611360f

File tree

4 files changed

+153
-164
lines changed

4 files changed

+153
-164
lines changed

compiler/rustc_passes/src/stability.rs

+17
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,25 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
891891
if let TyKind::Never = t.kind {
892892
self.fully_stable = false;
893893
}
894+
if let TyKind::BareFn(f) = t.kind {
895+
if rustc_target::spec::abi::is_stable(f.abi.name()).is_err() {
896+
self.fully_stable = false;
897+
}
898+
}
894899
intravisit::walk_ty(self, t)
895900
}
901+
902+
fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
903+
for ty in fd.inputs {
904+
self.visit_ty(ty)
905+
}
906+
if let hir::FnRetTy::Return(output_ty) = fd.output {
907+
match output_ty.kind {
908+
TyKind::Never => {} // `-> !` is stable
909+
_ => self.visit_ty(output_ty),
910+
}
911+
}
912+
}
896913
}
897914

898915
/// Given the list of enabled features that were not language features (i.e., that

compiler/rustc_target/src/spec/abi.rs

+109-159
Original file line numberDiff line numberDiff line change
@@ -109,175 +109,125 @@ pub enum AbiDisabled {
109109
Unrecognized,
110110
}
111111

112-
fn gate_feature_post(
112+
pub fn is_enabled(
113113
features: &rustc_feature::Features,
114-
feature: Symbol,
115114
span: Span,
116-
explain: &'static str,
115+
name: &str,
117116
) -> Result<(), AbiDisabled> {
118-
if !features.enabled(feature) && !span.allows_unstable(feature) {
119-
Err(AbiDisabled::Unstable { feature, explain })
120-
} else {
121-
Ok(())
117+
let s = is_stable(name);
118+
if let Err(AbiDisabled::Unstable { feature, .. }) = s {
119+
if features.enabled(feature) || span.allows_unstable(feature) {
120+
return Ok(());
121+
}
122122
}
123+
s
123124
}
124125

125-
pub fn is_enabled(
126-
features: &rustc_feature::Features,
127-
span: Span,
128-
name: &str,
129-
) -> Result<(), AbiDisabled> {
126+
pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
130127
match name {
131128
// Stable
132129
"Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
133130
| "system" => Ok(()),
134-
"rust-intrinsic" => {
135-
gate_feature_post(features, sym::intrinsics, span, "intrinsics are subject to change")
136-
}
137-
"platform-intrinsic" => gate_feature_post(
138-
features,
139-
sym::platform_intrinsics,
140-
span,
141-
"platform intrinsics are experimental and possibly buggy",
142-
),
143-
"vectorcall" => gate_feature_post(
144-
features,
145-
sym::abi_vectorcall,
146-
span,
147-
"vectorcall is experimental and subject to change",
148-
),
149-
"thiscall" => gate_feature_post(
150-
features,
151-
sym::abi_thiscall,
152-
span,
153-
"thiscall is experimental and subject to change",
154-
),
155-
"rust-call" => gate_feature_post(
156-
features,
157-
sym::unboxed_closures,
158-
span,
159-
"rust-call ABI is subject to change",
160-
),
161-
"rust-cold" => gate_feature_post(
162-
features,
163-
sym::rust_cold_cc,
164-
span,
165-
"rust-cold is experimental and subject to change",
166-
),
167-
"ptx-kernel" => gate_feature_post(
168-
features,
169-
sym::abi_ptx,
170-
span,
171-
"PTX ABIs are experimental and subject to change",
172-
),
173-
"unadjusted" => gate_feature_post(
174-
features,
175-
sym::abi_unadjusted,
176-
span,
177-
"unadjusted ABI is an implementation detail and perma-unstable",
178-
),
179-
"msp430-interrupt" => gate_feature_post(
180-
features,
181-
sym::abi_msp430_interrupt,
182-
span,
183-
"msp430-interrupt ABI is experimental and subject to change",
184-
),
185-
"x86-interrupt" => gate_feature_post(
186-
features,
187-
sym::abi_x86_interrupt,
188-
span,
189-
"x86-interrupt ABI is experimental and subject to change",
190-
),
191-
"amdgpu-kernel" => gate_feature_post(
192-
features,
193-
sym::abi_amdgpu_kernel,
194-
span,
195-
"amdgpu-kernel ABI is experimental and subject to change",
196-
),
197-
"avr-interrupt" | "avr-non-blocking-interrupt" => gate_feature_post(
198-
features,
199-
sym::abi_avr_interrupt,
200-
span,
201-
"avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
202-
),
203-
"efiapi" => gate_feature_post(
204-
features,
205-
sym::abi_efiapi,
206-
span,
207-
"efiapi ABI is experimental and subject to change",
208-
),
209-
"C-cmse-nonsecure-call" => gate_feature_post(
210-
features,
211-
sym::abi_c_cmse_nonsecure_call,
212-
span,
213-
"C-cmse-nonsecure-call ABI is experimental and subject to change",
214-
),
215-
"C-unwind" => gate_feature_post(
216-
features,
217-
sym::c_unwind,
218-
span,
219-
"C-unwind ABI is experimental and subject to change",
220-
),
221-
"stdcall-unwind" => gate_feature_post(
222-
features,
223-
sym::c_unwind,
224-
span,
225-
"stdcall-unwind ABI is experimental and subject to change",
226-
),
227-
"system-unwind" => gate_feature_post(
228-
features,
229-
sym::c_unwind,
230-
span,
231-
"system-unwind ABI is experimental and subject to change",
232-
),
233-
"thiscall-unwind" => gate_feature_post(
234-
features,
235-
sym::c_unwind,
236-
span,
237-
"thiscall-unwind ABI is experimental and subject to change",
238-
),
239-
"cdecl-unwind" => gate_feature_post(
240-
features,
241-
sym::c_unwind,
242-
span,
243-
"cdecl-unwind ABI is experimental and subject to change",
244-
),
245-
"fastcall-unwind" => gate_feature_post(
246-
features,
247-
sym::c_unwind,
248-
span,
249-
"fastcall-unwind ABI is experimental and subject to change",
250-
),
251-
"vectorcall-unwind" => gate_feature_post(
252-
features,
253-
sym::c_unwind,
254-
span,
255-
"vectorcall-unwind ABI is experimental and subject to change",
256-
),
257-
"aapcs-unwind" => gate_feature_post(
258-
features,
259-
sym::c_unwind,
260-
span,
261-
"aapcs-unwind ABI is experimental and subject to change",
262-
),
263-
"win64-unwind" => gate_feature_post(
264-
features,
265-
sym::c_unwind,
266-
span,
267-
"win64-unwind ABI is experimental and subject to change",
268-
),
269-
"sysv64-unwind" => gate_feature_post(
270-
features,
271-
sym::c_unwind,
272-
span,
273-
"sysv64-unwind ABI is experimental and subject to change",
274-
),
275-
"wasm" => gate_feature_post(
276-
features,
277-
sym::wasm_abi,
278-
span,
279-
"wasm ABI is experimental and subject to change",
280-
),
131+
"rust-intrinsic" => Err(AbiDisabled::Unstable {
132+
feature: sym::intrinsics,
133+
explain: "intrinsics are subject to change",
134+
}),
135+
"platform-intrinsic" => Err(AbiDisabled::Unstable {
136+
feature: sym::platform_intrinsics,
137+
explain: "platform intrinsics are experimental and possibly buggy",
138+
}),
139+
"vectorcall" => Err(AbiDisabled::Unstable {
140+
feature: sym::abi_vectorcall,
141+
explain: "vectorcall is experimental and subject to change",
142+
}),
143+
"thiscall" => Err(AbiDisabled::Unstable {
144+
feature: sym::abi_thiscall,
145+
explain: "thiscall is experimental and subject to change",
146+
}),
147+
"rust-call" => Err(AbiDisabled::Unstable {
148+
feature: sym::unboxed_closures,
149+
explain: "rust-call ABI is subject to change",
150+
}),
151+
"rust-cold" => Err(AbiDisabled::Unstable {
152+
feature: sym::rust_cold_cc,
153+
explain: "rust-cold is experimental and subject to change",
154+
}),
155+
"ptx-kernel" => Err(AbiDisabled::Unstable {
156+
feature: sym::abi_ptx,
157+
explain: "PTX ABIs are experimental and subject to change",
158+
}),
159+
"unadjusted" => Err(AbiDisabled::Unstable {
160+
feature: sym::abi_unadjusted,
161+
explain: "unadjusted ABI is an implementation detail and perma-unstable",
162+
}),
163+
"msp430-interrupt" => Err(AbiDisabled::Unstable {
164+
feature: sym::abi_msp430_interrupt,
165+
explain: "msp430-interrupt ABI is experimental and subject to change",
166+
}),
167+
"x86-interrupt" => Err(AbiDisabled::Unstable {
168+
feature: sym::abi_x86_interrupt,
169+
explain: "x86-interrupt ABI is experimental and subject to change",
170+
}),
171+
"amdgpu-kernel" => Err(AbiDisabled::Unstable {
172+
feature: sym::abi_amdgpu_kernel,
173+
explain: "amdgpu-kernel ABI is experimental and subject to change",
174+
}),
175+
"avr-interrupt" | "avr-non-blocking-interrupt" => Err(AbiDisabled::Unstable {
176+
feature: sym::abi_avr_interrupt,
177+
explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
178+
}),
179+
"efiapi" => Err(AbiDisabled::Unstable {
180+
feature: sym::abi_efiapi,
181+
explain: "efiapi ABI is experimental and subject to change",
182+
}),
183+
"C-cmse-nonsecure-call" => Err(AbiDisabled::Unstable {
184+
feature: sym::abi_c_cmse_nonsecure_call,
185+
explain: "C-cmse-nonsecure-call ABI is experimental and subject to change",
186+
}),
187+
"C-unwind" => Err(AbiDisabled::Unstable {
188+
feature: sym::c_unwind,
189+
explain: "C-unwind ABI is experimental and subject to change",
190+
}),
191+
"stdcall-unwind" => Err(AbiDisabled::Unstable {
192+
feature: sym::c_unwind,
193+
explain: "stdcall-unwind ABI is experimental and subject to change",
194+
}),
195+
"system-unwind" => Err(AbiDisabled::Unstable {
196+
feature: sym::c_unwind,
197+
explain: "system-unwind ABI is experimental and subject to change",
198+
}),
199+
"thiscall-unwind" => Err(AbiDisabled::Unstable {
200+
feature: sym::c_unwind,
201+
explain: "thiscall-unwind ABI is experimental and subject to change",
202+
}),
203+
"cdecl-unwind" => Err(AbiDisabled::Unstable {
204+
feature: sym::c_unwind,
205+
explain: "cdecl-unwind ABI is experimental and subject to change",
206+
}),
207+
"fastcall-unwind" => Err(AbiDisabled::Unstable {
208+
feature: sym::c_unwind,
209+
explain: "fastcall-unwind ABI is experimental and subject to change",
210+
}),
211+
"vectorcall-unwind" => Err(AbiDisabled::Unstable {
212+
feature: sym::c_unwind,
213+
explain: "vectorcall-unwind ABI is experimental and subject to change",
214+
}),
215+
"aapcs-unwind" => Err(AbiDisabled::Unstable {
216+
feature: sym::c_unwind,
217+
explain: "aapcs-unwind ABI is experimental and subject to change",
218+
}),
219+
"win64-unwind" => Err(AbiDisabled::Unstable {
220+
feature: sym::c_unwind,
221+
explain: "win64-unwind ABI is experimental and subject to change",
222+
}),
223+
"sysv64-unwind" => Err(AbiDisabled::Unstable {
224+
feature: sym::c_unwind,
225+
explain: "sysv64-unwind ABI is experimental and subject to change",
226+
}),
227+
"wasm" => Err(AbiDisabled::Unstable {
228+
feature: sym::wasm_abi,
229+
explain: "wasm ABI is experimental and subject to change",
230+
}),
281231
_ => Err(AbiDisabled::Unrecognized),
282232
}
283233
}

src/test/ui/stability-attribute/stability-attribute-trait-impl.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(staged_api)]
1+
#![feature(staged_api, never_type, c_unwind)]
22
//~^ ERROR module has missing stability attribute
33

44
#[stable(feature = "a", since = "1")]
@@ -23,7 +23,21 @@ impl StableTrait for UnstableType {}
2323
impl UnstableTrait for StableType {}
2424

2525
#[unstable(feature = "h", issue = "none")]
26+
impl StableTrait for ! {}
27+
28+
// Note: If C-unwind is stabilized, switch this to another (unstable) ABI.
29+
#[unstable(feature = "i", issue = "none")]
30+
impl StableTrait for extern "C-unwind" fn() {}
31+
32+
#[unstable(feature = "j", issue = "none")]
2633
//~^ ERROR an `#[unstable]` annotation here has no effect [ineffective_unstable_trait_impl]
2734
impl StableTrait for StableType {}
2835

36+
#[unstable(feature = "k", issue = "none")]
37+
//~^ ERROR an `#[unstable]` annotation here has no effect [ineffective_unstable_trait_impl]
38+
impl StableTrait for fn() -> ! {}
39+
40+
#[unstable(feature = "l", issue = "none")]
41+
impl StableTrait for fn() -> UnstableType {}
42+
2943
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
error: an `#[unstable]` annotation here has no effect
2-
--> $DIR/stability-attribute-trait-impl.rs:25:1
2+
--> $DIR/stability-attribute-trait-impl.rs:32:1
33
|
4-
LL | #[unstable(feature = "h", issue = "none")]
4+
LL | #[unstable(feature = "j", issue = "none")]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
88
= note: `#[deny(ineffective_unstable_trait_impl)]` on by default
99

10+
error: an `#[unstable]` annotation here has no effect
11+
--> $DIR/stability-attribute-trait-impl.rs:36:1
12+
|
13+
LL | #[unstable(feature = "k", issue = "none")]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
17+
1018
error: module has missing stability attribute
1119
--> $DIR/stability-attribute-trait-impl.rs:1:1
1220
|
13-
LL | / #![feature(staged_api)]
21+
LL | / #![feature(staged_api, never_type, c_unwind)]
1422
LL | |
1523
LL | |
1624
LL | | #[stable(feature = "a", since = "1")]
@@ -19,5 +27,5 @@ LL | |
1927
LL | | fn main() {}
2028
| |____________^
2129

22-
error: aborting due to 2 previous errors
30+
error: aborting due to 3 previous errors
2331

0 commit comments

Comments
 (0)