Skip to content

Commit 4e2d289

Browse files
committed
Witness selection should pick exact matches for effect overloads
You can overload a function based on its `async`-ness, and resolution is carried out based on async-ness of calling context. But during protocol conformance checking, for an `async` requirement we were accidentally choosing the non-`async overload instead of the `async` one. The `async` one is the choice people would expect, since the `async` requirement is in essence the "context" that forwards to the underlying witness. This intended behavior is also inferred from: #40088 The problem boiled down to a bad check when categorizing the witness matches prior to ranking them. Resolves rdar://109135488 / #60318
1 parent 08c4646 commit 4e2d289

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,9 +1196,13 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
11961196
matchKind = MatchKind::RenamedMatch;
11971197
else if (requiresNonSendable)
11981198
matchKind = MatchKind::RequiresNonSendable;
1199-
else if (getEffects(witness).containsOnly(getEffects(req)))
1199+
else if (getEffects(req) - getEffects(witness))
1200+
// when the difference is non-empty, the witness has fewer effects.
12001201
matchKind = MatchKind::FewerEffects;
12011202

1203+
assert(getEffects(req).contains(getEffects(witness))
1204+
&& "witness has more effects than requirement?");
1205+
12021206
// Success. Form the match result.
12031207
RequirementMatch result(witness,
12041208
matchKind,

0 commit comments

Comments
 (0)