Skip to content

Commit a014676

Browse files
committed
Return true if decl is package in isResilient (and other equv) funcs
Ref rdar://118947451
1 parent 24dc372 commit a014676

File tree

5 files changed

+256
-5
lines changed

5 files changed

+256
-5
lines changed

include/swift/AST/AccessScope.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class AccessScope {
7575
bool isFileScope() const;
7676
bool isInternal() const;
7777
bool isPackage() const;
78+
bool isPublicOrPackage() const { return isPublic() || isPackage(); }
7879

7980
/// Checks if the DeclContext of this (use site) access scope is more
8081
/// restrictive than that of the argument (decl site) based on the DeclContext

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,7 +2977,7 @@ bool AbstractStorageDecl::isFormallyResilient() const {
29772977
// Non-public global and static variables always have a
29782978
// fixed layout.
29792979
if (!getFormalAccessScope(/*useDC=*/nullptr,
2980-
/*treatUsableFromInlineAsPublic=*/true).isPublic())
2980+
/*treatUsableFromInlineAsPublic=*/true).isPublicOrPackage())
29812981
return false;
29822982

29832983
return true;
@@ -4915,7 +4915,7 @@ bool NominalTypeDecl::isFormallyResilient() const {
49154915
// Private, (unversioned) internal, and package types always have a
49164916
// fixed layout.
49174917
if (!getFormalAccessScope(/*useDC=*/nullptr,
4918-
/*treatUsableFromInlineAsPublic=*/true).isPublic())
4918+
/*treatUsableFromInlineAsPublic=*/true).isPublicOrPackage())
49194919
return false;
49204920

49214921
// Check for an explicit @_fixed_layout or @frozen attribute.

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -805,12 +805,12 @@ IsSerialized_t SILDeclRef::isSerialized() const {
805805
return IsSerialized;
806806
}
807807

808-
// Otherwise, check if the owning declaration is public.
808+
// Otherwise, check if the owning declaration is public or package.
809809
auto scope =
810810
d->getFormalAccessScope(/*useDC=*/nullptr,
811811
/*treatUsableFromInlineAsPublic=*/true);
812812

813-
if (scope.isPublic())
813+
if (scope.isPublicOrPackage())
814814
return IsSerialized;
815815
return IsNotSerialized;
816816
}
@@ -823,7 +823,7 @@ IsSerialized_t SILDeclRef::isSerialized() const {
823823
auto scope =
824824
nominal->getFormalAccessScope(/*useDC=*/nullptr,
825825
/*treatUsableFromInlineAsPublic=*/true);
826-
if (!scope.isPublic())
826+
if (!scope.isPublicOrPackage())
827827
return IsNotSerialized;
828828
if (nominal->isFormallyResilient())
829829
return IsNotSerialized;

test/Sema/package_resilience_access.swift renamed to test/Sema/package_non_resilient_access.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// REQUIRES: rdar118947451
2+
13
// RUN: %empty-directory(%t)
24
// RUN: split-file %s %t
35

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -emit-module %t/Utils.swift \
5+
// RUN: -module-name Utils -swift-version 5 -I %t \
6+
// RUN: -package-name mypkg \
7+
// RUN: -enable-library-evolution \
8+
// RUN: -emit-module -emit-module-path %t/Utils.swiftmodule
9+
10+
// RUN: %target-swift-frontend -typecheck %t/Client.swift -I %t -swift-version 5 -package-name mypkg -verify
11+
12+
// RUN: %target-swift-frontend -emit-sil %t/Client.swift -package-name mypkg -I %t > %t/Client.sil
13+
// RUN: %FileCheck %s < %t/Client.sil
14+
15+
16+
//--- Utils.swift
17+
18+
// Resilient; public. Acessed indirectly.
19+
public struct PublicStruct {
20+
public var data: Int
21+
}
22+
23+
// Non-resilient; non-public. Accessed directly.
24+
package struct PkgStruct {
25+
package var data: Int
26+
}
27+
28+
// Non-resilient but accessed indirectly since generic.
29+
package struct PkgStructGeneric<T> {
30+
package var data: T
31+
}
32+
33+
// Non-resilient but accessed indirectly; member is of a resilient type.
34+
package struct PkgStructWithPublicMember {
35+
package var member: PublicStruct
36+
}
37+
38+
// Non-resilient but accessed indirectly; contains existential.
39+
package struct PkgStructWithPublicExistential {
40+
package var member: any PublicProto
41+
}
42+
43+
// Non-resilient but accessed indirectly; contains existential.
44+
package struct PkgStructWithPkgExistential {
45+
package var member: any PkgProto
46+
}
47+
48+
// Resilient; public. Acessed indirectly.
49+
public protocol PublicProto {
50+
var data: Int { get set }
51+
}
52+
53+
// Non-resilient but acessed indirectly; existential.
54+
package protocol PkgProto {
55+
var data: Int { get set }
56+
}
57+
58+
59+
//--- Client.swift
60+
import Utils
61+
62+
package func f(_ arg: PublicStruct) -> Int {
63+
return arg.data
64+
}
65+
66+
// CHECK: // f(_:)
67+
// CHECK-NEXT: sil @$s6Client1fySi5Utils12PublicStructVF : $@convention(thin) (@in_guaranteed PublicStruct) -> Int {
68+
// CHECK-NEXT: // %0 "arg" // users: %3, %1
69+
// CHECK-NEXT: bb0(%0 : $*PublicStruct):
70+
// CHECK-NEXT: debug_value %0 : $*PublicStruct, let, name "arg", argno 1, expr op_deref // id: %1
71+
// CHECK-NEXT: %2 = alloc_stack $PublicStruct // users: %7, %6, %5, %3
72+
// CHECK-NEXT: copy_addr %0 to [init] %2 : $*PublicStruct // id: %3
73+
// CHECK-NEXT: // function_ref PublicStruct.data.getter
74+
// CHECK-NEXT: %4 = function_ref @$s5Utils12PublicStructV4dataSivg : $@convention(method) (@in_guaranteed PublicStruct) -> Int // user: %5
75+
// CHECK-NEXT: %5 = apply %4(%2) : $@convention(method) (@in_guaranteed PublicStruct) -> Int // user: %8
76+
// CHECK-NEXT: destroy_addr %2 : $*PublicStruct // id: %6
77+
// CHECK-NEXT: dealloc_stack %2 : $*PublicStruct // id: %7
78+
// CHECK-NEXT: return %5 : $Int // id: %8
79+
// CHECK-NEXT: } // end sil function '$s6Client1fySi5Utils12PublicStructVF'
80+
81+
// CHECK: // PublicStruct.data.getter
82+
// CHECK-NEXT: sil @$s5Utils12PublicStructV4dataSivg : $@convention(method) (@in_guaranteed PublicStruct) -> Int
83+
84+
package func g(_ arg: PkgStruct) -> Int {
85+
return arg.data
86+
}
87+
88+
// CHECK: // g(_:)
89+
// CHECK-NEXT: sil @$s6Client1gySi5Utils9PkgStructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> Int {
90+
// CHECK-NEXT: // %0 "arg" // users: %3, %1
91+
// CHECK-NEXT: bb0(%0 : $*PkgStruct):
92+
// CHECK-NEXT: debug_value %0 : $*PkgStruct, let, name "arg", argno 1, expr op_deref // id: %1
93+
// CHECK-NEXT: %2 = alloc_stack $PkgStruct // users: %7, %6, %5, %3
94+
// CHECK-NEXT: copy_addr %0 to [init] %2 : $*PkgStruct // id: %3
95+
// CHECK-NEXT: // function_ref PkgStruct.data.getter
96+
// CHECK-NEXT: %4 = function_ref @$s5Utils9PkgStructV4dataSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int // user: %5
97+
// CHECK-NEXT: %5 = apply %4(%2) : $@convention(method) (@in_guaranteed PkgStruct) -> Int // user: %8
98+
// CHECK-NEXT: destroy_addr %2 : $*PkgStruct // id: %6
99+
// CHECK-NEXT: dealloc_stack %2 : $*PkgStruct // id: %7
100+
// CHECK-NEXT: return %5 : $Int // id: %8
101+
// CHECK-NEXT: } // end sil function '$s6Client1gySi5Utils9PkgStructVF'
102+
103+
// CHECK: // PkgStruct.data.getter
104+
// CHECK-NEXT: sil @$s5Utils9PkgStructV4dataSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int
105+
106+
package func m<T>(_ arg: PkgStructGeneric<T>) -> T {
107+
return arg.data
108+
}
109+
110+
// CHECK: // m<A>(_:)
111+
// CHECK-NEXT: sil @$s6Client1myx5Utils16PkgStructGenericVyxGlF : $@convention(thin) <T> (@in_guaranteed PkgStructGeneric<T>) -> @out T {
112+
// CHECK-NEXT: // %0 "$return_value" // user: %6
113+
// CHECK-NEXT: // %1 "arg" // users: %4, %2
114+
// CHECK-NEXT: bb0(%0 : $*T, %1 : $*PkgStructGeneric<T>):
115+
// CHECK-NEXT: debug_value %1 : $*PkgStructGeneric<T>, let, name "arg", argno 1, expr op_deref // id: %2
116+
// CHECK-NEXT: %3 = alloc_stack $PkgStructGeneric<T> // users: %8, %7, %6, %4
117+
// CHECK-NEXT: copy_addr %1 to [init] %3 : $*PkgStructGeneric<T> // id: %4
118+
// CHECK-NEXT: // function_ref PkgStructGeneric.data.getter
119+
// CHECK-NEXT: %5 = function_ref @$s5Utils16PkgStructGenericV4dataxvg : $@convention(method) <τ_0_0> (@in_guaranteed PkgStructGeneric<τ_0_0>) -> @out τ_0_0 // user: %6
120+
// CHECK-NEXT: %6 = apply %5<T>(%0, %3) : $@convention(method) <τ_0_0> (@in_guaranteed PkgStructGeneric<τ_0_0>) -> @out τ_0_0
121+
// CHECK-NEXT: destroy_addr %3 : $*PkgStructGeneric<T> // id: %7
122+
// CHECK-NEXT: dealloc_stack %3 : $*PkgStructGeneric<T> // id: %8
123+
// CHECK-NEXT: %9 = tuple () // user: %10
124+
// CHECK-NEXT: return %9 : $() // id: %10
125+
// CHECK-NEXT: } // end sil function '$s6Client1myx5Utils16PkgStructGenericVyxGlF'
126+
127+
// CHECK: // PkgStructGeneric.data.getter
128+
// CHECK-NEXT: sil @$s5Utils16PkgStructGenericV4dataxvg : $@convention(method) <τ_0_0> (@in_guaranteed PkgStructGeneric<τ_0_0>) -> @out τ_0_0
129+
130+
131+
package func n(_ arg: PkgStructWithPublicMember) -> Int {
132+
return arg.member.data
133+
}
134+
135+
// CHECK: // n(_:)
136+
// CHECK-NEXT: sil @$s6Client1nySi5Utils25PkgStructWithPublicMemberVF : $@convention(thin) (@in_guaranteed PkgStructWithPublicMember) -> Int {
137+
// CHECK-NEXT: // %0 "arg" // users: %3, %1
138+
// CHECK-NEXT: bb0(%0 : $*PkgStructWithPublicMember):
139+
// CHECK-NEXT: debug_value %0 : $*PkgStructWithPublicMember, let, name "arg", argno 1, expr op_deref // id: %1
140+
// CHECK-NEXT: %2 = alloc_stack $PkgStructWithPublicMember // users: %16, %7, %6, %3
141+
// CHECK-NEXT: copy_addr %0 to [init] %2 : $*PkgStructWithPublicMember // id: %3
142+
// CHECK-NEXT: %4 = alloc_stack $PublicStruct // users: %15, %13, %9, %6
143+
// CHECK-NEXT: // function_ref PkgStructWithPublicMember.member.getter
144+
// CHECK-NEXT: %5 = function_ref @$s5Utils25PkgStructWithPublicMemberV6memberAA0eC0Vvg : $@convention(method) (@in_guaranteed PkgStructWithPublicMember) -> @out PublicStruct // user: %6
145+
// CHECK-NEXT: %6 = apply %5(%4, %2) : $@convention(method) (@in_guaranteed PkgStructWithPublicMember) -> @out PublicStruct
146+
// CHECK-NEXT: destroy_addr %2 : $*PkgStructWithPublicMember // id: %7
147+
// CHECK-NEXT: %8 = alloc_stack $PublicStruct // users: %14, %12, %11, %9
148+
// CHECK-NEXT: copy_addr %4 to [init] %8 : $*PublicStruct // id: %9
149+
// CHECK-NEXT: // function_ref PublicStruct.data.getter
150+
// CHECK-NEXT: %10 = function_ref @$s5Utils12PublicStructV4dataSivg : $@convention(method) (@in_guaranteed PublicStruct) -> Int // user: %11
151+
// CHECK-NEXT: %11 = apply %10(%8) : $@convention(method) (@in_guaranteed PublicStruct) -> Int // user: %17
152+
// CHECK-NEXT: destroy_addr %8 : $*PublicStruct // id: %12
153+
// CHECK-NEXT: destroy_addr %4 : $*PublicStruct // id: %13
154+
// CHECK-NEXT: dealloc_stack %8 : $*PublicStruct // id: %14
155+
// CHECK-NEXT: dealloc_stack %4 : $*PublicStruct // id: %15
156+
// CHECK-NEXT: dealloc_stack %2 : $*PkgStructWithPublicMember // id: %16
157+
// CHECK-NEXT: return %11 : $Int // id: %17
158+
// CHECK-NEXT: } // end sil function '$s6Client1nySi5Utils25PkgStructWithPublicMemberVF'
159+
160+
// CHECK: // PkgStructWithPublicMember.member.getter
161+
// CHECK-NEXT: sil @$s5Utils25PkgStructWithPublicMemberV6memberAA0eC0Vvg : $@convention(method) (@in_guaranteed PkgStructWithPublicMember) -> @out PublicStruct
162+
163+
164+
package func p(_ arg: PkgStructWithPublicExistential) -> any PublicProto {
165+
return arg.member
166+
}
167+
168+
// CHECK: // p(_:)
169+
// CHECK-NEXT: sil @$s6Client1py5Utils11PublicProto_pAC013PkgStructWithC11ExistentialVF : $@convention(thin) (@in_guaranteed PkgStructWithPublicExistential) -> @out any PublicProto {
170+
// CHECK-NEXT: // %0 "$return_value" // user: %6
171+
// CHECK-NEXT: // %1 "arg" // users: %4, %2
172+
// CHECK-NEXT: bb0(%0 : $*any PublicProto, %1 : $*PkgStructWithPublicExistential):
173+
// CHECK-NEXT: debug_value %1 : $*PkgStructWithPublicExistential, let, name "arg", argno 1, expr op_deref // id: %2
174+
// CHECK-NEXT: %3 = alloc_stack $PkgStructWithPublicExistential // users: %8, %7, %6, %4
175+
// CHECK-NEXT: copy_addr %1 to [init] %3 : $*PkgStructWithPublicExistential // id: %4
176+
// CHECK-NEXT: // function_ref PkgStructWithPublicExistential.member.getter
177+
// CHECK-NEXT: %5 = function_ref @$s5Utils30PkgStructWithPublicExistentialV6memberAA0E5Proto_pvg : $@convention(method) (@in_guaranteed PkgStructWithPublicExistential) -> @out any PublicProto // user: %6
178+
// CHECK-NEXT: %6 = apply %5(%0, %3) : $@convention(method) (@in_guaranteed PkgStructWithPublicExistential) -> @out any PublicProto
179+
// CHECK-NEXT: destroy_addr %3 : $*PkgStructWithPublicExistential // id: %7
180+
// CHECK-NEXT: dealloc_stack %3 : $*PkgStructWithPublicExistential // id: %8
181+
// CHECK-NEXT: %9 = tuple () // user: %10
182+
// CHECK-NEXT: return %9 : $() // id: %10
183+
// CHECK-NEXT: } // end sil function '$s6Client1py5Utils11PublicProto_pAC013PkgStructWithC11ExistentialVF'
184+
185+
// CHECK: // PkgStructWithPublicExistential.member.getter
186+
// CHECK-NEXT: sil @$s5Utils30PkgStructWithPublicExistentialV6memberAA0E5Proto_pvg : $@convention(method) (@in_guaranteed PkgStructWithPublicExistential) -> @out any PublicProto
187+
188+
package func q(_ arg: PkgStructWithPkgExistential) -> any PkgProto {
189+
return arg.member
190+
}
191+
192+
// CHECK: // q(_:)
193+
// CHECK-NEXT: sil @$s6Client1qy5Utils8PkgProto_pAC0c10StructWithC11ExistentialVF : $@convention(thin) (@in_guaranteed PkgStructWithPkgExistential) -> @out any PkgProto {
194+
// CHECK-NEXT: // %0 "$return_value" // user: %6
195+
// CHECK-NEXT: // %1 "arg" // users: %4, %2
196+
// CHECK-NEXT: bb0(%0 : $*any PkgProto, %1 : $*PkgStructWithPkgExistential):
197+
// CHECK-NEXT: debug_value %1 : $*PkgStructWithPkgExistential, let, name "arg", argno 1, expr op_deref // id: %2
198+
// CHECK-NEXT: %3 = alloc_stack $PkgStructWithPkgExistential // users: %8, %7, %6, %4
199+
// CHECK-NEXT: copy_addr %1 to [init] %3 : $*PkgStructWithPkgExistential // id: %4
200+
// CHECK-NEXT: // function_ref PkgStructWithPkgExistential.member.getter
201+
// CHECK-NEXT: %5 = function_ref @$s5Utils013PkgStructWithB11ExistentialV6memberAA0B5Proto_pvg : $@convention(method) (@in_guaranteed PkgStructWithPkgExistential) -> @out any PkgProto // user: %6
202+
// CHECK-NEXT: %6 = apply %5(%0, %3) : $@convention(method) (@in_guaranteed PkgStructWithPkgExistential) -> @out any PkgProto
203+
// CHECK-NEXT: destroy_addr %3 : $*PkgStructWithPkgExistential // id: %7
204+
// CHECK-NEXT: dealloc_stack %3 : $*PkgStructWithPkgExistential // id: %8
205+
// CHECK-NEXT: %9 = tuple () // user: %10
206+
// CHECK-NEXT: return %9 : $() // id: %10
207+
// CHECK-NEXT: } // end sil function '$s6Client1qy5Utils8PkgProto_pAC0c10StructWithC11ExistentialVF'
208+
209+
// CHECK: // PkgStructWithPkgExistential.member.getter
210+
// CHECK-NEXT: sil @$s5Utils013PkgStructWithB11ExistentialV6memberAA0B5Proto_pvg : $@convention(method) (@in_guaranteed PkgStructWithPkgExistential) -> @out any PkgProto
211+
212+
package func r(_ arg: PublicProto) -> Int {
213+
return arg.data
214+
}
215+
216+
// CHECK: // r(_:)
217+
// CHECK-NEXT: sil @$s6Client1rySi5Utils11PublicProto_pF : $@convention(thin) (@in_guaranteed any PublicProto) -> Int {
218+
// CHECK-NEXT: // %0 "arg" // users: %2, %1
219+
// CHECK-NEXT: bb0(%0 : $*any PublicProto):
220+
// CHECK-NEXT: debug_value %0 : $*any PublicProto, let, name "arg", argno 1, expr op_deref // id: %1
221+
// CHECK-NEXT: %2 = open_existential_addr immutable_access %0 : $*any PublicProto to $*@opened({{.*}}, any PublicProto) Self // users: %6, %5, %4, %3
222+
// CHECK-NEXT: %3 = alloc_stack $@opened("{{.*}}", any PublicProto) Self // type-defs: %2; users: %8, %7, %6, %4
223+
// CHECK-NEXT: copy_addr %2 to [init] %3 : $*@opened("{{.*}}", any PublicProto) Self // id: %4
224+
// CHECK-NEXT: %5 = witness_method $@opened("{{.*}}", any PublicProto) Self, #PublicProto.data!getter : <Self where Self : Utils.PublicProto> (Self) -> () -> Int, %2 : $*@opened("{{.*}}", any PublicProto) Self : $@convention(witness_method: PublicProto) <τ_0_0 where τ_0_0 : PublicProto> (@in_guaranteed τ_0_0) -> Int // type-defs: %2; user: %6
225+
// CHECK-NEXT: %6 = apply %5<@opened("{{.*}}", any PublicProto) Self>(%3) : $@convention(witness_method: PublicProto) <τ_0_0 where τ_0_0 : PublicProto> (@in_guaranteed τ_0_0) -> Int // type-defs: %2; user: %9
226+
// CHECK-NEXT: destroy_addr %3 : $*@opened("{{.*}}", any PublicProto) Self // id: %7
227+
// CHECK-NEXT: dealloc_stack %3 : $*@opened("{{.*}}", any PublicProto) Self // id: %8
228+
// CHECK-NEXT: return %6 : $Int // id: %9
229+
// CHECK-NEXT: } // end sil function '$s6Client1rySi5Utils11PublicProto_pF'
230+
231+
package func s(_ arg: PkgProto) -> Int {
232+
return arg.data
233+
}
234+
235+
// CHECK: // s(_:)
236+
// CHECK-NEXT: sil @$s6Client1sySi5Utils8PkgProto_pF : $@convention(thin) (@in_guaranteed any PkgProto) -> Int {
237+
// CHECK-NEXT: // %0 "arg" // users: %2, %1
238+
// CHECK-NEXT: bb0(%0 : $*any PkgProto):
239+
// CHECK-NEXT: debug_value %0 : $*any PkgProto, let, name "arg", argno 1, expr op_deref // id: %1
240+
// CHECK-NEXT: %2 = open_existential_addr immutable_access %0 : $*any PkgProto to $*@opened("{{.*}}", any PkgProto) Self // users: %6, %5, %4, %3
241+
// CHECK-NEXT: %3 = alloc_stack $@opened("{{.*}}", any PkgProto) Self // type-defs: %2; users: %8, %7, %6, %4
242+
// CHECK-NEXT: copy_addr %2 to [init] %3 : $*@opened("{{.*}}", any PkgProto) Self // id: %4
243+
// CHECK-NEXT: %5 = witness_method $@opened("{{.*}}", any PkgProto) Self, #PkgProto.data!getter : <Self where Self : Utils.PkgProto> (Self) -> () -> Int, %2 : $*@opened("{{.*}}", any PkgProto) Self : $@convention(witness_method: PkgProto) <τ_0_0 where τ_0_0 : PkgProto> (@in_guaranteed τ_0_0) -> Int // type-defs: %2; user: %6
244+
// CHECK-NEXT: %6 = apply %5<@opened("{{.*}}", any PkgProto) Self>(%3) : $@convention(witness_method: PkgProto) <τ_0_0 where τ_0_0 : PkgProto> (@in_guaranteed τ_0_0) -> Int // type-defs: %2; user: %9
245+
// CHECK-NEXT: destroy_addr %3 : $*@opened("{{.*}}", any PkgProto) Self // id: %7
246+
// CHECK-NEXT: dealloc_stack %3 : $*@opened("{{.*}}", any PkgProto) Self // id: %8
247+
// CHECK-NEXT: return %6 : $Int // id: %9
248+
// CHECK-NEXT: } // end sil function '$s6Client1sySi5Utils8PkgProto_pF'

0 commit comments

Comments
 (0)