Skip to content

Commit b773c49

Browse files
committed
Allow @isolated(any) mismatches in witness matching.
I'm not really convinced that this shouldn't be done by introducing a new kind of constraint rather than hacking in what are essentially conversions as "bind" constraints, but this is the most direct path for now. Fixes rdar://125394096
1 parent a89564b commit b773c49

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,6 +3041,13 @@ matchFunctionThrowing(ConstraintSystem &cs,
30413041
}
30423042
}
30433043

3044+
static bool isWitnessMatching(ConstraintLocatorBuilder locator) {
3045+
SmallVector<LocatorPathElt, 4> path;
3046+
(void) locator.getLocatorParts(path);
3047+
return (path.size() == 1 &&
3048+
path[0].is<LocatorPathElt::Witness>());
3049+
}
3050+
30443051
bool
30453052
ConstraintSystem::matchFunctionIsolations(FunctionType *func1,
30463053
FunctionType *func2,
@@ -3054,8 +3061,11 @@ ConstraintSystem::matchFunctionIsolations(FunctionType *func1,
30543061
// function-conversion score to make sure this solution is worse than
30553062
// an exact match.
30563063
// FIXME: there may be a better way. see https://github.com/apple/swift/pull/62514
3057-
auto matchIfConversion = [&]() -> bool {
3058-
if (kind < ConstraintKind::Subtype)
3064+
auto matchIfConversion = [&](bool isErasure = false) -> bool {
3065+
// We generally require a conversion here, but allow some lassitude
3066+
// if we're doing witness-matching.
3067+
if (kind < ConstraintKind::Subtype &&
3068+
!(isErasure && isWitnessMatching(locator)))
30593069
return false;
30603070
increaseScore(SK_FunctionConversion, locator);
30613071
return true;
@@ -3154,7 +3164,7 @@ ConstraintSystem::matchFunctionIsolations(FunctionType *func1,
31543164
// isolation as a conversion.
31553165
case FunctionTypeIsolation::Kind::NonIsolated:
31563166
case FunctionTypeIsolation::Kind::GlobalActor:
3157-
return matchIfConversion();
3167+
return matchIfConversion(/*erasure*/ true);
31583168

31593169
// Parameter isolation is value-dependent and can't be erased in the
31603170
// abstract, though. We need to be able to recover the isolation from
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -emit-silgen -enable-experimental-feature IsolatedAny %s -module-name test -swift-version 6 -disable-availability-checking | %FileCheck %s
2+
// REQUIRES: concurrency
3+
// REQUIRES: asserts
4+
5+
// rdar://125394096. This was a source compatibility failure in which adding
6+
// @isolated(any) to TaskGroup.addTask caused problems with a project that
7+
// introduced a protocol for different task group types.
8+
9+
struct A<T> {
10+
func enqueue(operation: @escaping @isolated(any) () async -> T) {}
11+
}
12+
13+
protocol Enqueuer {
14+
associatedtype Result
15+
func enqueue(operation: @escaping @Sendable () async -> Result)
16+
}
17+
18+
extension A : Enqueuer {}
19+
20+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s4test1AVyxGAA8EnqueuerA2aEP7enqueue9operationy6ResultQzyYaYbc_tFTW :
21+
// CHECK: bb0(%0 : @guaranteed $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>, %1 : $*A<τ_0_0>):
22+
// CHECK-NEXT: [[CONVERTED_FN:%.*]] = convert_function %0 : $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0> to $@Sendable @async @callee_guaranteed () -> @out τ_0_0
23+
// CHECK-NEXT: [[ISOLATION:%.*]] = enum $Optional<any Actor>, #Optional.none
24+
// CHECK-NEXT: [[FN_COPY:%.*]] = copy_value [[CONVERTED_FN]] : $@Sendable @async @callee_guaranteed () -> @out τ_0_0
25+
// CHECK-NEXT: // function_ref
26+
// CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sxIeghHr_xIeAghHr_lTR
27+
// CHECK-NEXT: partial_apply [callee_guaranteed] [isolated_any] [[THUNK]]<τ_0_0>([[ISOLATION]], [[FN_COPY]])
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-frontend -typecheck -enable-experimental-feature IsolatedAny -verify %s
2+
3+
struct A<T> {
4+
// expected-note @+1 {{candidate has non-matching type}}
5+
func enqueue(operation: @escaping @Sendable () async -> T) {}
6+
}
7+
8+
protocol AnnotatedEnqueuer {
9+
associatedtype Result
10+
11+
// expected-note @+1 {{protocol requires function}}
12+
func enqueue(operation: @escaping @isolated(any) () async -> Result)
13+
}
14+
15+
// expected-error @+1 {{type 'A<T>' does not conform to protocol 'AnnotatedEnqueuer'}}
16+
extension A : AnnotatedEnqueuer {}

0 commit comments

Comments
 (0)