Skip to content

Commit 97bb6b1

Browse files
committed
Prevent #if in @abi in module interfaces
When a language feature is used inside an `@abi` attribute, we should behave as though it was used on its counterpart. This was already half-implemented—we ensured the counterpart would use the feature—but we didn’t make the ABI decl aware that the counterpart was its parent for feature detection purposes. As a result, we would print `#if` inside the `@abi` attribute, which isn’t valid.
1 parent 8f75878 commit 97bb6b1

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

lib/AST/FeatureSet.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,12 @@ FeatureSet swift::getUniqueFeaturesUsed(Decl *decl) {
709709
// Remove all the features used by all enclosing declarations.
710710
Decl *enclosingDecl = decl;
711711
while (!features.empty()) {
712+
// If we were in an @abi attribute, collect from the API counterpart.
713+
auto abiRole = ABIRoleInfo(enclosingDecl);
714+
if (!abiRole.providesAPI() && abiRole.getCounterpart())
715+
enclosingDecl = abiRole.getCounterpart();
712716
// Find the next outermost enclosing declaration.
713-
if (auto accessor = dyn_cast<AccessorDecl>(enclosingDecl))
717+
else if (auto accessor = dyn_cast<AccessorDecl>(enclosingDecl))
714718
enclosingDecl = accessor->getStorage();
715719
else
716720
enclosingDecl = enclosingDecl->getDeclContext()->getAsDecl();

test/ModuleInterface/attrs.swift

+14
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ public struct MutatingTest {
8585
@abi(func abiSpiFunc())
8686
@_spi(spiGroup) public func abiSpiFunc() {}
8787

88+
// We should print feature guards outside, but not inside, an @abi attribute.
89+
@abi(func sendingABI() -> sending Any?)
90+
public func sendingABI() -> Any? { nil }
91+
// CHECK: #if {{.*}} && $ABIAttribute
92+
// CHECK: @abi(func sendingABI() -> sending Any?)
93+
// CHECK: public func sendingABI() -> Any?
94+
// CHECK: #elseif {{.*}} && $SendingArgsAndResults
95+
// CHECK: @_silgen_name("$s5attrs10sendingABIypSgyF")
96+
// CHECK: public func sendingABI() -> Any?
97+
// CHECK: #else
98+
// CHECK: @_silgen_name("$s5attrs10sendingABIypSgyF")
99+
// CHECK: public func sendingABI() -> Any?
100+
// CHECK: #endif
101+
88102
@concurrent
89103
public func testExecutionConcurrent() async {}
90104
// CHECK: @concurrent public func testExecutionConcurrent() async

0 commit comments

Comments
 (0)