Skip to content

Commit bfcbc95

Browse files
committed
AST: Inherit access level of opaque type decls from naming decl.
When an `OpaqueTypeDecl` is constructed, the access level attributes of the decl that names the opaque type are copied on to it. However, the `@usableFromInline` attribute is not permitted on every decl, so it does not get copied. This in turn causes effective access level computations for opaque types to fail to take `@usableFromInline` into account and that results in the emitted symbol getting the wrong linkage during IRGen. The fix is to make the effective access computation take this quirk of opaque types into account directly, instead of relying on copying of attributes. Resolves rdar://110544170
1 parent 14282f1 commit bfcbc95

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,6 +3867,12 @@ getAdjustedFormalAccess(const ValueDecl *VD, const DeclContext *useDC,
38673867
}
38683868

38693869
AccessLevel ValueDecl::getEffectiveAccess() const {
3870+
// Opaque type decls inherit accessibility from their naming decl.
3871+
if (auto *opaqueType = dyn_cast<OpaqueTypeDecl>(this)) {
3872+
if (auto *namingDecl = opaqueType->getNamingDecl())
3873+
return namingDecl->getEffectiveAccess();
3874+
}
3875+
38703876
auto effectiveAccess =
38713877
getAdjustedFormalAccess(this, /*useDC=*/nullptr,
38723878
/*treatUsableFromInlineAsPublic=*/true);

test/IRGen/Inputs/AlwaysInlineIntoWithOpaque.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,16 @@ public func testInlineWithOpaque() -> some P {
1414
}
1515
return 2.0
1616
}
17+
18+
@_alwaysEmitIntoClient
19+
public func testInlineWithOpaqueUsableFromInline() -> some P {
20+
if #available(macOS 9.0, *) {
21+
return usableFromInline()
22+
}
23+
return 4.0
24+
}
25+
26+
@usableFromInline
27+
func usableFromInline() -> some P {
28+
return 3
29+
}

test/IRGen/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ extension Int : P {
66

77
extension Double : P {
88
}
9+
10+
@usableFromInline
11+
func usableFromInline() -> some P {
12+
return 3
13+
}

test/IRGen/opaque_result_alwaysInlineIntoClient.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque %S/Inputs/AlwaysInlineIntoWithOpaque.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque)
2+
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque -enable-library-evolution %S/Inputs/AlwaysInlineIntoWithOpaque.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque)
33
// RUN: %target-codesign %t/%target-library-name(AlwaysInlineIntoWithOpaque)
44
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -lAlwaysInlineIntoWithOpaque -module-name main -I %t -L %t %s -o %t/a.out
55
// RUN: %target-codesign %t/a.out
66
// RUN: %target-run %t/a.out | %FileCheck %s
77

8-
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque %S/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque)
8+
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque -enable-library-evolution %S/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque)
99
// RUN: %target-codesign %t/a.out
1010
// RUN: %target-run %t/a.out | %FileCheck %s
1111

@@ -27,3 +27,11 @@ public func test() {
2727

2828
test()
2929
// CHECK: 1
30+
31+
public func testUsableFromInline() {
32+
let p = testInlineWithOpaqueUsableFromInline()
33+
print(p)
34+
}
35+
36+
testUsableFromInline()
37+
// CHECK: 3

test/TBD/opaque_result_type.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ public func dynReplacement(x: String) -> some P {
7777
return "replaced"
7878
}
7979

80+
@usableFromInline
81+
func ufi() -> some O {
82+
return 1
83+
}
84+
8085
extension String: P {
8186
public func poo() -> some O {
8287
return 0

0 commit comments

Comments
 (0)