Skip to content

Commit 540455a

Browse files
authored
Merge pull request #34468 from kavon/objc-async-70543421
[concurrency] Overload resolution for async-looking ObjC methods
2 parents 33452e1 + 403a268 commit 540455a

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

lib/Sema/CSStep.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,13 +578,15 @@ bool DisjunctionStep::shouldStopAt(const DisjunctionChoice &choice) const {
578578
auto delta = LastSolvedChoice->second - getCurrentScore();
579579
bool hasUnavailableOverloads = delta.Data[SK_Unavailable] > 0;
580580
bool hasFixes = delta.Data[SK_Fix] > 0;
581+
bool hasAsyncMismatch = delta.Data[SK_AsyncSyncMismatch] > 0;
581582
auto isBeginningOfPartition = choice.isBeginningOfPartition();
582583

583584
// Attempt to short-circuit evaluation of this disjunction only
584-
// if the disjunction choice we are comparing to did not involve
585-
// selecting unavailable overloads or result in fixes being
586-
// applied to reach a solution.
587-
return !hasUnavailableOverloads && !hasFixes &&
585+
// if the disjunction choice we are comparing to did not involve:
586+
// 1. selecting unavailable overloads
587+
// 2. result in fixes being applied to reach a solution
588+
// 3. selecting an overload that results in an async/sync mismatch
589+
return !hasUnavailableOverloads && !hasFixes && !hasAsyncMismatch &&
588590
(isBeginningOfPartition ||
589591
shortCircuitDisjunctionAt(choice, lastChoice));
590592
}

test/Concurrency/Inputs/Delegate.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef Delegate_h
2+
#define Delegate_h
3+
4+
@import Foundation;
5+
6+
@interface Request : NSObject
7+
8+
@end
9+
10+
@interface Delegate : NSObject
11+
12+
- (void)makeRequest1:(Request * _Nonnull)request completionHandler:(void (^ _Nullable)(void))handler;
13+
14+
- (void)makeRequest2:(NSObject * _Nonnull)request completionHandler:(void (^ _Nullable)(void))handler;
15+
16+
- (void)makeRequest3:(Request * _Nullable)request completionHandler:(void (^ _Nullable)(void))handler;
17+
18+
@end
19+
20+
21+
#endif
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-concurrency -typecheck -verify -import-objc-header %S/Inputs/Delegate.h %s
2+
3+
// REQUIRES: objc_interop
4+
5+
6+
// overload resolution should pick sync version in a sync context
7+
func syncContext() {
8+
let r = Request()
9+
let d = Delegate()
10+
d.makeRequest1(r) // NOTE: this use to trigger an overload resolution error, see SR-13760
11+
d.makeRequest2(r)
12+
d.makeRequest3(r)
13+
}
14+
15+
// overload resolution should pick async version in an async context
16+
func asyncNoAwait() async {
17+
let r = Request()
18+
let d = Delegate()
19+
d.makeRequest1(r) // expected-error {{call is 'async' but is not marked with 'await'}}
20+
d.makeRequest2(r) // expected-error {{call is 'async' but is not marked with 'await'}}
21+
d.makeRequest3(r) // expected-error {{call is 'async' but is not marked with 'await'}}
22+
}
23+
24+
25+
func asyncWithAwait() async {
26+
let r = Request()
27+
let d = Delegate()
28+
await d.makeRequest1(r)
29+
await d.makeRequest2(r)
30+
await d.makeRequest3(r)
31+
}

0 commit comments

Comments
 (0)