Skip to content

Commit 106decb

Browse files
committed
GSB: Try harder to handle a combination of a superclass and conformance requirement
A protocol conformance requirement together with a superclass requirement can collapse down to a same-type requirement if the protocol itself has a 'where' clause: protocol P { associatedtype T where T == Self } class C : P {} extension P where T : C {} (Self : P) and (Self.T : C) imply that (Self == C), because protocol P says that Self.T == Self, and the witness of P.T in C is C, so when we substitute that in we get Self == C. Part of rdar://problem/80503090.
1 parent 4dc7657 commit 106decb

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8281,24 +8281,42 @@ GenericSignature GenericSignatureBuilder::rebuildSignatureWithoutRedundantRequir
82818281
}
82828282

82838283
auto subjectType = req.getSubjectType();
8284-
subjectType = stripBoundDependentMemberTypes(subjectType);
8285-
auto resolvedSubjectType =
8286-
resolveDependentMemberTypes(*this, subjectType,
8287-
ArchetypeResolutionKind::WellFormed);
8284+
auto resolvedSubject =
8285+
maybeResolveEquivalenceClass(subjectType,
8286+
ArchetypeResolutionKind::WellFormed,
8287+
/*wantExactPotentialArchetype=*/false);
8288+
8289+
auto *resolvedEquivClass = resolvedSubject.getEquivalenceClass(*this);
8290+
Type resolvedSubjectType;
8291+
if (resolvedEquivClass != nullptr)
8292+
resolvedSubjectType = resolvedEquivClass->getAnchor(*this, { });
82888293

82898294
// This can occur if the combination of a superclass requirement and
82908295
// protocol conformance requirement force a type to become concrete.
82918296
//
82928297
// FIXME: Is there a more principled formulation of this?
8293-
if (req.getKind() == RequirementKind::Superclass &&
8294-
!resolvedSubjectType->isTypeParameter()) {
8295-
newBuilder.addRequirement(Requirement(RequirementKind::SameType,
8296-
subjectType, resolvedSubjectType),
8297-
getRebuiltSource(req.getSource()), nullptr);
8298-
continue;
8298+
if (req.getKind() == RequirementKind::Superclass) {
8299+
if (resolvedSubject.getAsConcreteType()) {
8300+
auto unresolvedSubjectType = stripBoundDependentMemberTypes(subjectType);
8301+
newBuilder.addRequirement(Requirement(RequirementKind::SameType,
8302+
unresolvedSubjectType,
8303+
resolvedSubject.getAsConcreteType()),
8304+
getRebuiltSource(req.getSource()), nullptr);
8305+
continue;
8306+
}
8307+
8308+
if (resolvedEquivClass->concreteType) {
8309+
auto unresolvedSubjectType = stripBoundDependentMemberTypes(
8310+
resolvedSubjectType);
8311+
newBuilder.addRequirement(Requirement(RequirementKind::SameType,
8312+
unresolvedSubjectType,
8313+
resolvedEquivClass->concreteType),
8314+
getRebuiltSource(req.getSource()), nullptr);
8315+
continue;
8316+
}
82998317
}
83008318

8301-
assert(resolvedSubjectType->isTypeParameter());
8319+
assert(resolvedSubjectType && resolvedSubjectType->isTypeParameter());
83028320

83038321
if (auto optReq = createRequirement(req.getKind(), resolvedSubjectType,
83048322
req.getRHS(), getGenericParams())) {

test/Generics/rdar75656022.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ struct OriginalExampleWithWarning<A, B> where A : P2, B : P2, A.T == B.T {
4848
init<C, D, E>(_: C)
4949
where C : P1,
5050
D : P1, // expected-warning {{redundant conformance constraint 'D' : 'P1'}}
51-
// expected-note@-1 {{conformance constraint 'C.T' : 'P1' implied here}}
52-
C.T : P1, // expected-warning {{redundant conformance constraint 'C.T' : 'P1'}}
51+
C.T : P1, // expected-warning {{redundant conformance constraint 'D' : 'P1'}}
52+
// expected-note@-1 {{conformance constraint 'D' : 'P1' implied here}}
5353
A == S1<C, C.T.T, S2<C.T>>,
5454
C.T == D,
5555
E == D.T { }

test/Generics/rdar80503090.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,12 @@ extension P where T : Q {
1717
missing()
1818
}
1919
}
20+
21+
class C : P {}
22+
23+
extension P where T : C {
24+
// CHECK-LABEL: Generic signature: <Self where Self == C>
25+
func test() {
26+
missing()
27+
}
28+
}

0 commit comments

Comments
 (0)