@@ -1872,6 +1872,31 @@ static bool isRetroactiveConformance(const RootProtocolConformance *root) {
1872
1872
return conformance->isRetroactive ();
1873
1873
}
1874
1874
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
+
1875
1900
// / Determine whether the given protocol conformance contains a retroactive
1876
1901
// / protocol conformance anywhere in it.
1877
1902
static bool containsRetroactiveConformance (
@@ -1899,24 +1924,10 @@ static bool containsRetroactiveConformance(
1899
1924
1900
1925
// If the conformance is conditional and any of the substitutions used to
1901
1926
// 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
+ });
1920
1931
}
1921
1932
1922
1933
void ASTMangler::appendRetroactiveConformances (SubstitutionMap subMap,
@@ -4169,48 +4180,27 @@ void ASTMangler::appendAnyProtocolConformance(
4169
4180
void ASTMangler::appendConcreteProtocolConformance (
4170
4181
const ProtocolConformance *conformance,
4171
4182
GenericSignature sig) {
4172
- auto module = conformance->getDeclContext ()->getParentModule ();
4173
-
4174
4183
// Conforming type.
4175
4184
Type conformingType = conformance->getType ();
4176
4185
if (conformingType->hasArchetype ())
4177
4186
conformingType = conformingType->mapTypeOutOfContext ();
4178
- appendType (conformingType->getCanonicalType ( ), sig);
4187
+ appendType (conformingType->getReducedType (sig ), sig);
4179
4188
4180
4189
// Protocol conformance reference.
4181
4190
appendProtocolConformanceRef (conformance->getRootConformance ());
4182
4191
4183
4192
// Conditional conformance requirements.
4184
4193
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);
4209
4200
appendListSeparator (firstRequirement);
4210
- break ;
4211
- }
4212
- }
4213
- }
4201
+ return false ;
4202
+ });
4203
+
4214
4204
if (firstRequirement)
4215
4205
appendOperator (" y" );
4216
4206
0 commit comments