Skip to content

Commit 00eee36

Browse files
authored
Merge pull request #76115 from xedin/rdar-131524246
[CSBindings] Don't prioritize closures that are assigned to overloade…
2 parents db0b5db + c8690b3 commit 00eee36

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,30 @@ bool BindingSet::favoredOverDisjunction(Constraint *disjunction) const {
13181318
// Such type variables might be connected to closure as well
13191319
// e.g. when result type is optional, so it makes sense to
13201320
// open closure before attempting such disjunction.
1321-
return boundType->lookThroughAllOptionalTypes()->is<TypeVariableType>();
1321+
if (auto *typeVar = boundType->lookThroughAllOptionalTypes()
1322+
->getAs<TypeVariableType>()) {
1323+
auto fixedType = CS.getFixedType(typeVar);
1324+
// Handles "assignment to an overloaded member" pattern where
1325+
// type variable that represents the destination is bound to an
1326+
// l-value type during constraint generation. See \c genAssignDestType.
1327+
//
1328+
// Note that in all other circumstances we won't be here if the
1329+
// type variable that presents the closure is connected to a
1330+
// disjunction because that would mark closure as "delayed".
1331+
if (fixedType && fixedType->is<LValueType>()) {
1332+
auto lvalueObjTy = fixedType->castTo<LValueType>()->getObjectType();
1333+
// Prefer closure only if it's not connected to the type variable
1334+
// that represents l-value object type of the assignment destination.
1335+
// Eagerly attempting closure first could result in missing some of
1336+
// the contextual annotations i.e. `@Sendable`.
1337+
if (auto *lvalueObjVar = lvalueObjTy->getAs<TypeVariableType>())
1338+
return !AdjacentVars.count(lvalueObjVar);
1339+
}
1340+
1341+
return true;
1342+
}
1343+
1344+
return false;
13221345
}
13231346

13241347
// If this is a collection literal type, it's preferrable to bind it
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -strict-concurrency=complete
3+
// RUN: %target-typecheck-verify-swift -swift-version 6
4+
5+
// rdar://131524246
6+
7+
protocol P: Sendable {
8+
typealias Block = @Sendable () -> Void
9+
var block: Block? { get }
10+
}
11+
12+
extension P {
13+
var block: Block? { nil }
14+
}
15+
16+
final class Impl: P, @unchecked Sendable {
17+
var block: Block?
18+
}
19+
20+
func test(_ v: Impl) {
21+
v.block = {} // Ok, no warnings or errors
22+
}

0 commit comments

Comments
 (0)