@@ -1608,8 +1608,22 @@ bool ProtocolConformance::isCanonical() const {
16081608
16091609 switch (getKind ()) {
16101610 case ProtocolConformanceKind::Self:
1611- case ProtocolConformanceKind::Normal:
1611+ case ProtocolConformanceKind::Normal: {
1612+ return true ;
1613+ }
16121614 case ProtocolConformanceKind::Builtin: {
1615+ // Check that the generic signature of the conformance is canonical.
1616+ auto builtinConformance = cast<BuiltinProtocolConformance>(this );
1617+ if (builtinConformance->getGenericSignature ()
1618+ && !builtinConformance->getGenericSignature ()->isCanonical ()) {
1619+ return false ;
1620+ }
1621+ // Check that the satisfied conditional requirements are canonical.
1622+ for (auto &requirement : builtinConformance->getConditionalRequirements ()) {
1623+ if (!requirement.isCanonical ()) {
1624+ return false ;
1625+ }
1626+ }
16131627 return true ;
16141628 }
16151629 case ProtocolConformanceKind::Inherited: {
@@ -1638,11 +1652,25 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
16381652
16391653 switch (getKind ()) {
16401654 case ProtocolConformanceKind::Self:
1641- case ProtocolConformanceKind::Normal:
1642- case ProtocolConformanceKind::Builtin: {
1655+ case ProtocolConformanceKind::Normal: {
16431656 // Root conformances are always canonical by construction.
16441657 return this ;
16451658 }
1659+ case ProtocolConformanceKind::Builtin: {
1660+ // Canonicalize the subject type of the builtin conformance.
1661+ auto &Ctx = getType ()->getASTContext ();
1662+ auto builtinConformance = cast<BuiltinProtocolConformance>(this );
1663+ SmallVector<Requirement, 4 > canonicalRequirements;
1664+ for (auto &reqt : builtinConformance->getConditionalRequirements ()) {
1665+ canonicalRequirements.push_back (reqt.getCanonical ());
1666+ }
1667+ return Ctx.getBuiltinConformance (
1668+ builtinConformance->getType ()->getCanonicalType (),
1669+ builtinConformance->getProtocol (),
1670+ builtinConformance->getGenericSignature ().getCanonicalSignature (),
1671+ canonicalRequirements,
1672+ builtinConformance->getBuiltinConformanceKind ());
1673+ }
16461674
16471675 case ProtocolConformanceKind::Inherited: {
16481676 auto &Ctx = getType ()->getASTContext ();
0 commit comments