Skip to content

Commit 033d86b

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 9fbc6f7 commit 033d86b

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

lib/AST/FeatureSet.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,12 @@ FeatureSet swift::getUniqueFeaturesUsed(Decl *decl) {
687687
// Remove all the features used by all enclosing declarations.
688688
Decl *enclosingDecl = decl;
689689
while (!features.empty()) {
690+
// If we were in an @abi attribute, collect from the API counterpart.
691+
auto abiRole = ABIRoleInfo(enclosingDecl);
692+
if (!abiRole.providesAPI() && abiRole.getCounterpart())
693+
enclosingDecl = abiRole.getCounterpart();
690694
// Find the next outermost enclosing declaration.
691-
if (auto accessor = dyn_cast<AccessorDecl>(enclosingDecl))
695+
else if (auto accessor = dyn_cast<AccessorDecl>(enclosingDecl))
692696
enclosingDecl = accessor->getStorage();
693697
else
694698
enclosingDecl = enclosingDecl->getDeclContext()->getAsDecl();

test/ModuleInterface/attrs.swift

Lines changed: 14 additions & 0 deletions
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)