Skip to content

Commit 5bb40ae

Browse files
committed
Sema: Fix doesMemberHaveUnfulfillableConstraintsWithExistentialBase() for generic context
We don't want to pass in the outer generic signature here. The base type's constraint type is written in terms of archetypes, and we run generic signature queries against it with types appearing in the protocol member. Since the protocol member has Self at depth 0, index 0, prepending the outer generic signature to the opened existential signature would produce incorrect results.
1 parent f24cf9a commit 5bb40ae

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6023,7 +6023,7 @@ void ConstraintSystem::maybeProduceFallbackDiagnostic(
60236023
/// Because opened archetypes are not part of the surface language, these
60246024
/// constraints render the member inaccessible.
60256025
static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase(
6026-
Type baseTy, const ValueDecl *member, const DeclContext *useDC) {
6026+
Type baseTy, const ValueDecl *member) {
60276027
const auto sig =
60286028
member->getInnermostDeclContext()->getGenericSignatureOfContext();
60296029

@@ -6060,7 +6060,7 @@ static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase(
60606060
return Action::Stop;
60616061
}
60626062
} isDependentOnSelfWalker(member->getASTContext().getOpenedArchetypeSignature(
6063-
baseTy, useDC->getGenericSignatureOfContext()));
6063+
baseTy, GenericSignature()));
60646064

60656065
for (const auto &req : sig.getRequirements()) {
60666066
switch (req.getKind()) {
@@ -6121,8 +6121,7 @@ bool ConstraintSystem::isMemberAvailableOnExistential(
61216121
}
61226122

61236123
if (doesMemberHaveUnfulfillableConstraintsWithExistentialBase(baseTy,
6124-
member,
6125-
DC)) {
6124+
member)) {
61266125
return false;
61276126
}
61286127

test/decl/protocol/existential_member_accesses_self_assoctype.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,8 @@ extension UnfulfillableGenericRequirements {
560560
A: Sequence, A.Element: Sequence,
561561
U.A == A.Element.Element {}
562562
func method7<U>(_: U) where U: UnfulfillableGenericRequirements & Class<Self> {}
563+
564+
func method8<U>(_: U) where U == Self.A {}
563565
}
564566
do {
565567
let exist: any UnfulfillableGenericRequirements
@@ -579,6 +581,19 @@ do {
579581
exist.method7(false)
580582
// expected-error@-1 {{instance method 'method7' requires that 'U' conform to 'UnfulfillableGenericRequirements'}}
581583
// expected-error@-2 {{member 'method7' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
584+
585+
exist.method8(false)
586+
// expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
587+
}
588+
589+
// Make sure this also works in a generic context!
590+
struct G<X, Y, Z> {
591+
func doIt() {
592+
let exist: any UnfulfillableGenericRequirements
593+
594+
exist.method8(false)
595+
// expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
596+
}
582597
}
583598
protocol UnfulfillableGenericRequirementsDerived1: UnfulfillableGenericRequirements where A == Bool {}
584599
protocol UnfulfillableGenericRequirementsDerived2: UnfulfillableGenericRequirements where A == Class<Self> {}

0 commit comments

Comments
 (0)