mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
RequirementMachine: Don't call ProtocolDecl::getSuperclass() in concrete contraction
This changes the minimized signature in a very narrow edge case.
If you have
class C : P {}
and also
protocol P : C {}
protocol P where Self : C {}
then <T where T : P, T : C> now becomes <T : P> both with spellings;
before, the first one gave <T : P> and the second <T : C>.
This commit is contained in:
@@ -624,19 +624,26 @@ bool ConcreteContraction::performConcreteContraction(
|
||||
|
||||
auto superclassTy = *found->second.begin();
|
||||
|
||||
for (const auto *proto : pair.second) {
|
||||
if (auto otherSuperclassTy = proto->getSuperclass()) {
|
||||
if (Debug) {
|
||||
llvm::dbgs() << "@ Subject type of superclass requirement "
|
||||
<< subjectType << " : " << superclassTy
|
||||
<< " conforms to "<< proto->getName()
|
||||
<< " which has a superclass bound "
|
||||
<< otherSuperclassTy << "\n";
|
||||
}
|
||||
for (auto *proto : pair.second) {
|
||||
auto *module = proto->getParentModule();
|
||||
if (module->lookupConformance(superclassTy, proto)) {
|
||||
auto genericSig = proto->getGenericSignature();
|
||||
// FIXME: If we end up here while building the requirement
|
||||
// signature of `proto`, we will hit a request cycle.
|
||||
if (auto otherSuperclassTy = genericSig->getSuperclassBound(
|
||||
proto->getSelfInterfaceType())) {
|
||||
if (Debug) {
|
||||
llvm::dbgs() << "@ Subject type of superclass requirement "
|
||||
<< subjectType << " : " << superclassTy
|
||||
<< " conforms to "<< proto->getName()
|
||||
<< " which has a superclass bound "
|
||||
<< otherSuperclassTy << "\n";
|
||||
}
|
||||
|
||||
if (superclassTy->isEqual(otherSuperclassTy)) {
|
||||
Superclasses.erase(subjectType);
|
||||
break;
|
||||
if (superclassTy->isEqual(otherSuperclassTy)) {
|
||||
Superclasses.erase(subjectType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,3 +52,9 @@ func foo5<T : SubSuperP>(_: T) {}
|
||||
// CHECK-NEXT: Generic signature: <T where T : Q, T.[Q]T : SubSuperP>
|
||||
func foo6<T : Q>(_: T) where T.T : SubSuperP {}
|
||||
|
||||
protocol POther where Self : COther {}
|
||||
class COther : POther {}
|
||||
|
||||
// CHECK-LABEL: .foo7@
|
||||
// CHECK-NEXT: Generic signature: <T where T : POther>
|
||||
func foo7<T>(_: T) where T : COther, T : POther {}
|
||||
Reference in New Issue
Block a user