Skip to content

Commit babf807

Browse files
authored
Merge pull request #71709 from calda/cal--65921
[SE-0286] Fix issue where forward scanning default value heuristic wouldn't be applied in Swift 6 mode
2 parents 42e43ed + 63e9bfc commit babf807

File tree

3 files changed

+139
-5
lines changed

3 files changed

+139
-5
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,8 +563,6 @@ static bool matchCallArgumentsImpl(
563563
// backward-match rule that skips this parameter if doing so is the only
564564
// way to successfully match arguments to parameters.
565565
if (!parameterRequiresArgument(params, paramInfo, paramIdx) &&
566-
!param.getPlainType()->getASTContext().LangOpts.hasFeature(
567-
Feature::ForwardTrailingClosures) &&
568566
anyParameterRequiresArgument(
569567
params, paramInfo, paramIdx + 1,
570568
nextArgIdx + 1 < numArgs

test/expr/postfix/call/forward_trailing_closure_errors.swift

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,98 @@ func testUnlabeledParamMatching(i: Int, fn: ((Int) -> Int) -> Void) {
1717
fn { $0 + i} // okay because the parameter label is empty
1818
}
1919

20-
// When "fuzzy matching is disabled, this will fail.
21-
func forwardMatchFailure( // expected-note{{declared here}}
20+
func forwardMatchFailure(
2221
onError: ((any Error) -> Void)? = nil,
2322
onCompletion: (Int) -> Void
2423
) { }
2524

2625
func testForwardMatchFailure() {
2726
forwardMatchFailure { x in
2827
print(x)
29-
} // expected-error{{missing argument for parameter 'onCompletion' in call}}{{4-4= onCompletion: <#(Int) -> Void#>}}
28+
}
29+
}
30+
31+
func sheet(
32+
isPresented: Bool,
33+
onDismiss: (() -> Void)? = nil,
34+
content: () -> String
35+
) -> String {
36+
content()
37+
}
38+
39+
func testSwiftUISheetExample() {
40+
_ = sheet(isPresented: true) {
41+
"Hello world"
42+
}
43+
44+
_ = sheet(isPresented: true) {
45+
print("Was dismissed")
46+
} content: {
47+
"Hello world"
48+
}
49+
}
50+
51+
// https://github.com/apple/swift/issues/65921
52+
func issue_65921(onStart: ((String) -> Void)? = nil, onEnd: (String) -> Void) { }
53+
54+
func testIssue65921() {
55+
issue_65921 { end in
56+
_ = end
57+
}
58+
59+
issue_65921 { start in
60+
_ = start
61+
} onEnd: { end in
62+
_ = end
63+
}
64+
}
65+
66+
struct BlockObserver {
67+
var startHandler: ((Any) -> Void)? = nil
68+
var produceHandler: ((Any, Any) -> Void)? = nil
69+
var finishHandler: ((Any, Any, Any) -> Void)? = nil
70+
}
71+
72+
func testBlockObserverExample() {
73+
// This was valid under the backwards scan rule in Swift 5 but is no longer valid in Swift 6
74+
_ = BlockObserver { _, _, _ in } // expected-error {{contextual closure type '(Any) -> Void' expects 1 argument, but 3 were used in closure body}}
75+
76+
_ = BlockObserver { _ in } produceHandler: { _, _ in }
77+
_ = BlockObserver { _ in } finishHandler: { _, _, _ in }
78+
79+
_ = BlockObserver { _ in }
80+
produceHandler: { _, _ in }
81+
finishHandler: { _, _, _ in }
82+
}
83+
84+
func trailingClosures(
85+
arg1: () -> Void,
86+
arg2: () -> Void = {},
87+
arg3: () -> Void = {}
88+
) {}
89+
90+
func testTrailingClosures() {
91+
trailingClosures { print("Hello!") }
92+
trailingClosures { print("Hello,") } arg3: { print("world!") }
93+
}
94+
95+
// In Swift 5 mode either f or g can be used as a trailing closure.
96+
// In Swift 6 mode only f can be used as a trailing closure.
97+
func trailingClosureEitherDirection(
98+
f: (Int) -> Int = { $0 }, g: (Int, Int) -> Int = { $0 + $1 }
99+
) { }
100+
101+
func testTrailingClosureEitherDirection() {
102+
trailingClosureEitherDirection { -$0 }
103+
trailingClosureEitherDirection { $0 * $1 } // expected-error{{contextual closure type '(Int) -> Int' expects 1 argument, but 2 were used in closure body}}
104+
}
105+
106+
// This example was allowed as a trailing closure in Swift 5 mode but is no longer allowed in Swift 6 mode
107+
struct AccidentalReorder {
108+
let content: () -> Int
109+
var optionalInt: Int?
110+
}
111+
112+
func testAccidentalReorder() {
113+
_ = AccidentalReorder(optionalInt: 17) { 42 } // expected-error{{incorrect argument label in call (have 'optionalInt:_:', expected 'content:optionalInt:')}}
30114
}

test/expr/postfix/call/forward_trailing_closure_fuzzy.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,55 @@ struct AccidentalReorder { // expected-note{{'init(content:optionalInt:)' declar
5858
func testAccidentalReorder() {
5959
_ = AccidentalReorder(optionalInt: 17) { 42 } // expected-warning{{backward matching of the unlabeled trailing closure is deprecated; label the argument with 'content' to suppress this warning}}
6060
}
61+
62+
func sheet(
63+
isPresented: Bool,
64+
onDismiss: (() -> Void)? = nil,
65+
content: () -> String
66+
) -> String {
67+
content()
68+
}
69+
70+
func testSwiftUISheetExample() {
71+
_ = sheet(isPresented: true) {
72+
"Hello world"
73+
}
74+
75+
_ = sheet(isPresented: true) {
76+
print("Was dismissed")
77+
} content: {
78+
"Hello world"
79+
}
80+
}
81+
82+
// https://github.com/apple/swift/issues/65921
83+
func issue_65921(onStart: ((String) -> Void)? = nil, onEnd: (String) -> Void) { }
84+
85+
func testIssue65921() {
86+
issue_65921 { end in
87+
_ = end
88+
}
89+
90+
issue_65921 { start in
91+
_ = start
92+
} onEnd: { end in
93+
_ = end
94+
}
95+
}
96+
97+
struct BlockObserver { // expected-note {{'init(startHandler:produceHandler:finishHandler:)' declared here}}
98+
var startHandler: ((Any) -> Void)? = nil
99+
var produceHandler: ((Any, Any) -> Void)? = nil
100+
var finishHandler: ((Any, Any, Any) -> Void)? = nil
101+
}
102+
103+
func testBlockObserverExample() {
104+
_ = BlockObserver { _, _, _ in } // expected-warning {{backward matching of the unlabeled trailing closure is deprecated; label the argument with 'finishHandler' to suppress this warning}}
105+
106+
_ = BlockObserver { _ in } produceHandler: { _, _ in }
107+
_ = BlockObserver { _ in } finishHandler: { _, _, _ in }
108+
109+
_ = BlockObserver { _ in }
110+
produceHandler: { _, _ in }
111+
finishHandler: { _, _, _ in }
112+
}

0 commit comments

Comments
 (0)