Skip to content

Commit b9262e5

Browse files
committed
Sema: Allow default arguments to access @usableFromInline decls.
The restriction that default arguments be disallowed from accessing `@usableFromInline` decls is overbearing for library developers who need to write non-trivial code to compute a default value, since it forces them to either write a verbose closure inline in the function signature or expose a `public` helper function which unnecessarily expands API surface. A `@usableFromInline` function a more reasonable way to encapsulate a verbose default value computation. This reverses the semantic changes included in #15666. Resolves rdar://112093794.
1 parent 69cbb45 commit b9262e5

File tree

3 files changed

+18
-28
lines changed

3 files changed

+18
-28
lines changed

lib/AST/DeclContext.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,11 @@ swift::FragileFunctionKindRequest::evaluate(Evaluator &evaluator,
471471
}
472472

473473
auto effectiveAccess =
474-
VD->getFormalAccessScope(/*useDC=*/nullptr,
475-
/*treatUsableFromInlineAsPublic=*/true);
476-
auto formalAccess =
477-
VD->getFormalAccessScope(/*useDC=*/nullptr,
478-
/*treatUsableFromInlineAsPublic=*/false);
474+
VD->getFormalAccessScope(/*useDC=*/nullptr,
475+
/*treatUsableFromInlineAsPublic=*/true);
479476
if (effectiveAccess.isPublic()) {
480477
return {FragileFunctionKind::DefaultArgument,
481-
!formalAccess.isPublic()};
478+
/*allowUsableFromInline=*/true};
482479
}
483480

484481
return {FragileFunctionKind::None,

test/Constraints/type_inference_from_default_exprs.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ protocol StorageType {
208208
var identifier: String { get }
209209
}
210210

211-
class Storage { // expected-note {{class 'Storage' is not public}}
211+
class Storage { // expected-note {{class 'Storage' is not '@usableFromInline' or public}}
212212
}
213213

214214
extension Storage {
@@ -256,7 +256,7 @@ struct S61061_3<T> where T:Hashable {
256256

257257
// https://github.com/apple/swift/issues/62025
258258
// Syntactic checks are not run on the default argument expressions
259-
public struct MyStruct {} // expected-note {{initializer 'init()' is not public}}
259+
public struct MyStruct {} // expected-note {{initializer 'init()' is not '@usableFromInline' or public}}
260260
public func issue62025_with_init<T>(_: T = MyStruct()) {}
261261
// expected-error@-1 {{initializer 'init()' is internal and cannot be referenced from a default argument value}}
262262
public func issue62025_with_type<T>(_: T = Storage.self) {}

test/decl/func/default-values-swift4.swift

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-testing
33

44
private func privateFunction() {}
5-
// expected-note@-1 2{{global function 'privateFunction()' is not public}}
5+
// expected-note@-1 2{{global function 'privateFunction()' is not '@usableFromInline' or public}}
66
fileprivate func fileprivateFunction() {}
7-
// expected-note@-1 2{{global function 'fileprivateFunction()' is not public}}
7+
// expected-note@-1 2{{global function 'fileprivateFunction()' is not '@usableFromInline' or public}}
88
func internalFunction() {}
9-
// expected-note@-1 2{{global function 'internalFunction()' is not public}}
10-
@usableFromInline func versionedFunction() {}
11-
// expected-note@-1 4{{global function 'versionedFunction()' is not public}}
9+
// expected-note@-1 2{{global function 'internalFunction()' is not '@usableFromInline' or public}}
10+
@usableFromInline func usableFromInlineFunction() {}
1211
public func publicFunction() {}
1312

1413
func internalIntFunction() -> Int {}
15-
// expected-note@-1 {{global function 'internalIntFunction()' is not public}}
14+
// expected-note@-1 {{global function 'internalIntFunction()' is not '@usableFromInline' or public}}
1615

1716
private func privateFunction2() {}
1817
// expected-note@-1 {{global function 'privateFunction2()' is not '@usableFromInline' or public}}
@@ -31,7 +30,7 @@ func internalFunctionWithDefaultValue(
3130

3231
publicFunction()
3332
// OK
34-
versionedFunction()
33+
usableFromInlineFunction()
3534
// OK
3635
internalFunction()
3736
// OK
@@ -44,16 +43,14 @@ func internalFunctionWithDefaultValue(
4443
}(),
4544
y: Int = internalIntFunction()) {}
4645

47-
@usableFromInline func versionedFunctionWithDefaultValue(
46+
@usableFromInline func usableFromInlineFunctionWithDefaultValue(
4847
x: Int = {
4948
struct Nested {}
5049
// expected-error@-1 {{type 'Nested' cannot be nested inside a default argument value}}
5150

52-
// FIXME: Some errors below are diagnosed twice
53-
5451
publicFunction()
5552
// OK
56-
versionedFunction()
53+
usableFromInlineFunction()
5754
// OK
5855
internalFunction2()
5956
// expected-error@-1 {{global function 'internalFunction2()' is internal and cannot be referenced from a default argument value}}
@@ -76,8 +73,7 @@ public func publicFunctionWithDefaultValue(
7673

7774
publicFunction()
7875

79-
versionedFunction()
80-
// expected-error@-1 {{global function 'versionedFunction()' is internal and cannot be referenced from a default argument value}}
76+
usableFromInlineFunction()
8177

8278
internalFunction()
8379
// expected-error@-1 {{global function 'internalFunction()' is internal and cannot be referenced from a default argument value}}
@@ -101,18 +97,16 @@ public class MyClass {
10197
public func evilCode(
10298
x: Int = {
10399
let _ = publicFunction()
104-
let _ = versionedFunction()
105-
// expected-error@-1 {{global function 'versionedFunction()' is internal and cannot be referenced from a default argument value}}
100+
let _ = usableFromInlineFunction()
106101

107102
func localFunction() {
108103
publicFunction()
109-
versionedFunction()
110-
// expected-error@-1 {{global function 'versionedFunction()' is internal and cannot be referenced from a default argument value}}
104+
usableFromInlineFunction()
111105
}
112106
return 0
113107
}()) {}
114108

115-
private func privateIntFunction() -> Int {} // expected-note {{global function 'privateIntFunction()' is not public}}
109+
private func privateIntFunction() -> Int {} // expected-note {{global function 'privateIntFunction()' is not '@usableFromInline' or public}}
116110

117111
public struct HasSubscript {
118112
public subscript(x: Int = {
@@ -121,8 +115,7 @@ public struct HasSubscript {
121115

122116
publicFunction()
123117

124-
versionedFunction()
125-
// expected-error@-1 {{global function 'versionedFunction()' is internal and cannot be referenced from a default argument value}}
118+
usableFromInlineFunction()
126119

127120
internalFunction()
128121
// expected-error@-1 {{global function 'internalFunction()' is internal and cannot be referenced from a default argument value}}

0 commit comments

Comments
 (0)