Skip to content

Commit 68e3488

Browse files
authored
Merge pull request swiftlang#71779 from apple/es-pb
Allow resilience bypassing package optimization for all decls within a package boundary.
2 parents d6824a7 + 10c0b8a commit 68e3488

File tree

4 files changed

+40
-25
lines changed

4 files changed

+40
-25
lines changed

include/swift/AST/Decl.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4080,20 +4080,36 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
40804080

40814081
void setBraces(SourceRange braces) { Braces = braces; }
40824082

4083-
/// Should this declaration behave as if it must be accessed
4084-
/// resiliently, even when we're building a non-resilient module?
4083+
/// Returns whether this declaration is resilient at the definition site, i.e.
4084+
/// must be accessed resiliently even when its defining module is built
4085+
/// non-resiliently.
40854086
///
40864087
/// This is used for diagnostics, because we do not want a behavior
40874088
/// change between builds with resilience enabled and disabled.
40884089
bool isFormallyResilient() const;
40894090

4090-
/// Do we need to use resilient access patterns outside of this type's
4091-
/// resilience domain?
4091+
/// Returns whether this decl is resilient at the definition site
4092+
/// \c isFormallyResilient or whether its defining module
4093+
/// is built resiliently.
40924094
bool isResilient() const;
40934095

4094-
/// Do we need to use resilient access patterns when accessing this
4095-
/// type from the given module?
4096-
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;
4096+
/// Returns whether this decl is accessed non/resiliently at the _use_ site
4097+
/// in \p accessingModule, depending on \p expansion.
4098+
///
4099+
/// If \p expansion is maximal, the decl could be treated as non-resilient
4100+
/// even though the decl is resilient by definition or its defining module is built
4101+
/// resiliently. For example, if accessing a decl defined in the same module or
4102+
/// another module in the same package as the \p accessingModule, the
4103+
/// decl could be treated as non-resilient (with package optimization enabled in
4104+
/// case of different modules); this enables bypassing resilience checks at the
4105+
/// use site so the decl can be accessed directly.
4106+
///
4107+
/// \p accessingModule The module from which this decl is accessed. Might
4108+
/// be the same module as its defining module.
4109+
/// \p expansion Used to determine whether non-resilience / direct access
4110+
/// to this decl is possible.
4111+
bool isResilient(ModuleDecl *accessingModule,
4112+
ResilienceExpansion expansion) const;
40974113

40984114
/// Determine whether we have already attempted to add any
40994115
/// implicitly-defined initializers to this declaration.

lib/AST/Decl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4215,10 +4215,8 @@ bool ValueDecl::hasOpenAccess(const DeclContext *useDC) const {
42154215

42164216
bool ValueDecl::bypassResilienceInPackage(ModuleDecl *accessingModule) const {
42174217
return getASTContext().LangOpts.EnableBypassResilienceInPackage &&
4218-
getModuleContext()->inSamePackage(accessingModule) &&
4219-
!getModuleContext()->isBuiltFromInterface() &&
4220-
getFormalAccessScope(/*useDC=*/nullptr,
4221-
/*treatUsableFromInlineAsPublic=*/true).isPackage();
4218+
getModuleContext()->inSamePackage(accessingModule) &&
4219+
!getModuleContext()->isBuiltFromInterface();
42224220
}
42234221

42244222
/// Given the formal access level for using \p VD, compute the scope where

test/SILGen/package_bypass_resilience.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ func foo() {
3434
// CHECK: sil hidden [ossa] @$s6Client3fooyyF : $@convention(thin) () -> () {
3535
// CHECK-DEFAULT: [[F_REF:%.*]] = function_ref @$s5Utils9PkgStructV6pkgVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int
3636
// CHECK-DEFAULT: sil package_external @$s5Utils9PkgStructV6pkgVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int
37-
// CHECK-BYPASS: [[ADDR:%.*]] = struct_element_addr %7 : $*PkgStruct, #PkgStruct.pkgVar
37+
// CHECK-BYPASS: [[ADDR:%.*]] = struct_element_addr {{.*}} : $*PkgStruct, #PkgStruct.pkgVar
3838

3939
func bar() {
4040
print(PubStruct().pubVar)
4141
}
4242

4343
// CHECK: sil hidden [ossa] @$s6Client3baryyF : $@convention(thin) () -> () {
44-
// CHECK: [[F_REF:%.*]] = function_ref @$s5Utils9PubStructV6pubVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int
45-
// CHECK: sil @$s5Utils9PubStructV6pubVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int
44+
// CHECK-DEFAULT: [[F_REF:%.*]] = function_ref @$s5Utils9PubStructV6pubVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int
45+
// CHECK-DEFAULT: sil @$s5Utils9PubStructV6pubVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int
46+
// CHECK-BYPASS: [[ADDR:%.*]] = struct_element_addr {{.*}} : $*PubStruct, #PubStruct.pubVar

test/Sema/package_resilience_bypass_exhaustive_switch.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public enum FrozenPublicEnum {
3838
//--- ClientDefault.swift
3939
import Utils
4040

41-
func f(_ arg: PkgEnum) -> Int {
41+
package func f(_ arg: PkgEnum) -> Int {
4242
switch arg { // expected-warning {{switch covers known cases, but 'PkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
4343
case .one:
4444
return 1
@@ -47,7 +47,7 @@ func f(_ arg: PkgEnum) -> Int {
4747
}
4848
}
4949

50-
func g(_ arg: UfiPkgEnum) -> Int {
50+
package func g(_ arg: UfiPkgEnum) -> Int {
5151
switch arg { // expected-warning {{switch covers known cases, but 'UfiPkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
5252
case .one:
5353
return 1
@@ -74,33 +74,33 @@ public func k(_ arg: FrozenPublicEnum) -> Int {
7474
}
7575
}
7676

77+
7778
//--- ClientOptimized.swift
7879
import Utils
7980

80-
// No warning with optimization to bypass resilience checks for package enums.
81-
func f(_ arg: PkgEnum) -> Int {
82-
switch arg {
81+
// With optimization enabled to bypass resilience checks within
82+
// a package boundary, public (non-frozen) or package enums no
83+
// longer require `@unknown default` in source code switch stmts.
84+
package func f(_ arg: PkgEnum) -> Int {
85+
switch arg { // no-warning
8386
case .one:
8487
return 1
8588
case .two(let val):
8689
return 2 + val
8790
}
8891
}
8992

90-
// Warning still shows up for usableFromInline package enum as the optimization is targeted for
91-
// decls with package access, not the elevated public access. This might be allowed later.
92-
func g(_ arg: UfiPkgEnum) -> Int {
93-
switch arg { // expected-warning {{switch covers known cases, but 'UfiPkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
93+
package func g(_ arg: UfiPkgEnum) -> Int {
94+
switch arg { // no-warning
9495
case .one:
9596
return 1
9697
case .two(let val):
9798
return 2 + val
9899
}
99100
}
100101

101-
// Warning still shows up for public enum as the optimization is targeted for package types.
102102
public func h(_ arg: PublicEnum) -> Int {
103-
switch arg { // expected-warning {{switch covers known cases, but 'PublicEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
103+
switch arg { // no-warning
104104
case .one:
105105
return 1
106106
case .two(let val):

0 commit comments

Comments
 (0)