Skip to content

Commit 175ffe2

Browse files
committed
[Sema][GSB] Fix crash on cond conformances with invalid req
Fixes crashes related to retrieving a generic signature that is currently being built. This happens when a conditional conformance has a invalid requirement where the subject is the 'self' type and the constraint is a protocol to which 'self' already conforms. The most trivial case is when this latter conformance is the conditional conformance itself.
1 parent cd5acad commit 175ffe2

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4721,12 +4721,21 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
47214721
// type that makes sense to use here, but, in practice, all
47224722
// getLookupConformanceFns used in here don't use that parameter anyway.
47234723
auto dependentType = CanType();
4724-
auto conformance =
4725-
getLookupConformanceFn()(dependentType, subjectType, proto->getDecl());
47264724

4727-
// FIXME: diagnose if there's no conformance.
4728-
if (conformance) {
4729-
addConditionalRequirements(*this, *conformance, inferForModule);
4725+
auto D = getGenericParams().front()->getDecl();
4726+
auto DC = D ? D->getDeclContext() : nullptr;
4727+
auto NTD = DC ? DC->getAsNominalTypeOrNominalTypeExtensionContext()
4728+
: nullptr;
4729+
auto subjectNTD = subjectType->getAnyNominal();
4730+
4731+
if (!NTD || !subjectNTD || NTD != subjectNTD) {
4732+
auto conformance =
4733+
getLookupConformanceFn()(dependentType, subjectType,
4734+
proto->getDecl());
4735+
// FIXME: diagnose if there's no conformance.
4736+
if (conformance) {
4737+
addConditionalRequirements(*this, *conformance, inferForModule);
4738+
}
47304739
}
47314740
}
47324741
}

test/decl/ext/generic.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,23 @@ extension GenericClass where Self : P3 { }
144144
// expected-error@-1{{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'GenericClass'?}} {{30-34=GenericClass}}
145145
// expected-error@-2{{type 'GenericClass<T>' in conformance requirement does not refer to a generic parameter or associated type}}
146146

147+
protocol Prot1 {}
148+
protocol Prot2 {}
149+
protocol Prot3 {}
150+
protocol Prot4 {}
151+
protocol Prot5 {}
152+
153+
extension GenericClass: Prot1 where T: Prot1 {}
154+
extension GenericClass: Prot2 where Self: Prot1 {}
155+
// expected-error@-1 {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'GenericClass'?}}
156+
// expected-error@-2 {{type 'GenericClass<T>' in conformance requirement does not refer to a generic parameter or associated type}}
157+
extension GenericClass: Prot3 where GenericClass<T>: Prot1 {}
158+
// expected-error @-1 {{type 'GenericClass<T>' in conformance requirement does not refer to a generic parameter or associated type}}
159+
extension GenericClass: Prot4 where GenericClass<Int>: Prot1 {}
160+
// expected-error @-1 {{type 'GenericClass<Int>' in conformance requirement does not refer to a generic parameter or associated type}}
161+
extension GenericClass: Prot5 where GenericClass: Prot5 {}
162+
// expected-error @-1 {{type 'GenericClass<T>' in conformance requirement does not refer to a generic parameter or associated type}}
163+
147164
protocol P4 {
148165
associatedtype T
149166
init(_: T)

0 commit comments

Comments
 (0)