@@ -1872,6 +1872,31 @@ static bool isRetroactiveConformance(const RootProtocolConformance *root) {
18721872 return conformance->isRetroactive ();
18731873}
18741874
1875+ template <typename Fn>
1876+ static bool forEachConditionalConformance (const ProtocolConformance *conformance,
1877+ Fn fn) {
1878+ auto *rootConformance = conformance->getRootConformance ();
1879+
1880+ auto subMap = conformance->getSubstitutionMap ();
1881+ for (auto requirement : rootConformance->getConditionalRequirements ()) {
1882+ if (requirement.getKind () != RequirementKind::Conformance)
1883+ continue ;
1884+ ProtocolDecl *proto = requirement.getProtocolDecl ();
1885+ auto conformance = subMap.lookupConformance (
1886+ requirement.getFirstType ()->getCanonicalType (), proto);
1887+ if (conformance.isInvalid ()) {
1888+ // This should only happen when mangling invalid ASTs, but that happens
1889+ // for indexing purposes.
1890+ continue ;
1891+ }
1892+
1893+ if (fn (requirement.getFirstType ().subst (subMap), conformance))
1894+ return true ;
1895+ }
1896+
1897+ return false ;
1898+ }
1899+
18751900// / Determine whether the given protocol conformance contains a retroactive
18761901// / protocol conformance anywhere in it.
18771902static bool containsRetroactiveConformance (
@@ -1899,24 +1924,10 @@ static bool containsRetroactiveConformance(
18991924
19001925 // If the conformance is conditional and any of the substitutions used to
19011926 // satisfy the conditions are retroactive, it's retroactive.
1902- auto subMap = conformance->getSubstitutionMap ();
1903- for (auto requirement : rootConformance->getConditionalRequirements ()) {
1904- if (requirement.getKind () != RequirementKind::Conformance)
1905- continue ;
1906- ProtocolDecl *proto = requirement.getProtocolDecl ();
1907- auto conformance = subMap.lookupConformance (
1908- requirement.getFirstType ()->getCanonicalType (), proto);
1909- if (conformance.isInvalid ()) {
1910- // This should only happen when mangling invalid ASTs, but that happens
1911- // for indexing purposes.
1912- continue ;
1913- }
1914- if (containsRetroactiveConformance (conformance)) {
1915- return true ;
1916- }
1917- }
1918-
1919- return false ;
1927+ return forEachConditionalConformance (conformance,
1928+ [&](Type substType, ProtocolConformanceRef substConf) -> bool {
1929+ return containsRetroactiveConformance (substConf);
1930+ });
19201931}
19211932
19221933void ASTMangler::appendRetroactiveConformances (SubstitutionMap subMap,
@@ -4169,48 +4180,27 @@ void ASTMangler::appendAnyProtocolConformance(
41694180void ASTMangler::appendConcreteProtocolConformance (
41704181 const ProtocolConformance *conformance,
41714182 GenericSignature sig) {
4172- auto module = conformance->getDeclContext ()->getParentModule ();
4173-
41744183 // Conforming type.
41754184 Type conformingType = conformance->getType ();
41764185 if (conformingType->hasArchetype ())
41774186 conformingType = conformingType->mapTypeOutOfContext ();
4178- appendType (conformingType->getCanonicalType ( ), sig);
4187+ appendType (conformingType->getReducedType (sig ), sig);
41794188
41804189 // Protocol conformance reference.
41814190 appendProtocolConformanceRef (conformance->getRootConformance ());
41824191
41834192 // Conditional conformance requirements.
41844193 bool firstRequirement = true ;
4185- for (const auto &conditionalReq : conformance->getConditionalRequirements ()) {
4186- switch (conditionalReq.getKind ()) {
4187- case RequirementKind::SameShape:
4188- llvm_unreachable (" Same-shape requirement not supported here" );
4189- case RequirementKind::Layout:
4190- case RequirementKind::SameType:
4191- case RequirementKind::Superclass:
4192- continue ;
4193-
4194- case RequirementKind::Conformance: {
4195- auto type = conditionalReq.getFirstType ();
4196- if (type->hasArchetype ())
4197- type = type->mapTypeOutOfContext ();
4198- CanType canType = type->getReducedType (sig);
4199- auto proto = conditionalReq.getProtocolDecl ();
4200-
4201- ProtocolConformanceRef conformance;
4202-
4203- if (canType->isTypeParameter () || canType->is <OpaqueTypeArchetypeType>()){
4204- conformance = ProtocolConformanceRef (proto);
4205- } else {
4206- conformance = module ->lookupConformance (canType, proto);
4207- }
4208- appendAnyProtocolConformance (sig, canType, conformance);
4194+ forEachConditionalConformance (conformance,
4195+ [&](Type substType, ProtocolConformanceRef substConf) -> bool {
4196+ if (substType->hasArchetype ())
4197+ substType = substType->mapTypeOutOfContext ();
4198+ CanType canType = substType->getReducedType (sig);
4199+ appendAnyProtocolConformance (sig, canType, substConf);
42094200 appendListSeparator (firstRequirement);
4210- break ;
4211- }
4212- }
4213- }
4201+ return false ;
4202+ });
4203+
42144204 if (firstRequirement)
42154205 appendOperator (" y" );
42164206
0 commit comments