28
28
#include " swift/AST/MacroDiscriminatorContext.h"
29
29
#include " swift/AST/Module.h"
30
30
#include " swift/AST/Ownership.h"
31
+ #include " swift/AST/PackConformance.h"
31
32
#include " swift/AST/ParameterList.h"
32
33
#include " swift/AST/PrettyStackTrace.h"
33
34
#include " swift/AST/ProtocolConformance.h"
@@ -1871,20 +1872,11 @@ static bool isRetroactiveConformance(const RootProtocolConformance *root) {
1871
1872
return conformance->isRetroactive ();
1872
1873
}
1873
1874
1874
- // / Determine whether the given protocol conformance contains a retroactive
1875
- // / protocol conformance anywhere in it.
1876
- static bool containsRetroactiveConformance (
1877
- const ProtocolConformance *conformance,
1878
- ModuleDecl *module ) {
1879
- // If the root conformance is retroactive, it's retroactive.
1880
- const RootProtocolConformance *rootConformance =
1881
- conformance->getRootConformance ();
1882
- if (isRetroactiveConformance (rootConformance) &&
1883
- conformanceHasIdentity (rootConformance))
1884
- return true ;
1875
+ template <typename Fn>
1876
+ static bool forEachConditionalConformance (const ProtocolConformance *conformance,
1877
+ Fn fn) {
1878
+ auto *rootConformance = conformance->getRootConformance ();
1885
1879
1886
- // If the conformance is conditional and any of the substitutions used to
1887
- // satisfy the conditions are retroactive, it's retroactive.
1888
1880
auto subMap = conformance->getSubstitutionMap ();
1889
1881
for (auto requirement : rootConformance->getConditionalRequirements ()) {
1890
1882
if (requirement.getKind () != RequirementKind::Conformance)
@@ -1897,18 +1889,49 @@ static bool containsRetroactiveConformance(
1897
1889
// for indexing purposes.
1898
1890
continue ;
1899
1891
}
1900
- if (conformance. isConcrete () &&
1901
- containsRetroactiveConformance (conformance. getConcrete (), module )) {
1892
+
1893
+ if ( fn (requirement. getFirstType (). subst (subMap), conformance))
1902
1894
return true ;
1903
- }
1904
1895
}
1905
1896
1906
1897
return false ;
1907
1898
}
1908
1899
1900
+ // / Determine whether the given protocol conformance contains a retroactive
1901
+ // / protocol conformance anywhere in it.
1902
+ static bool containsRetroactiveConformance (
1903
+ ProtocolConformanceRef conformanceRef) {
1904
+ if (!conformanceRef.isPack () && !conformanceRef.isConcrete ())
1905
+ return false ;
1906
+
1907
+ if (conformanceRef.isPack ()) {
1908
+ for (auto patternConf : conformanceRef.getPack ()->getPatternConformances ()) {
1909
+ if (containsRetroactiveConformance (patternConf))
1910
+ return true ;
1911
+ }
1912
+
1913
+ return false ;
1914
+ }
1915
+
1916
+ auto *conformance = conformanceRef.getConcrete ();
1917
+
1918
+ // If the root conformance is retroactive, it's retroactive.
1919
+ const RootProtocolConformance *rootConformance =
1920
+ conformance->getRootConformance ();
1921
+ if (isRetroactiveConformance (rootConformance) &&
1922
+ conformanceHasIdentity (rootConformance))
1923
+ return true ;
1924
+
1925
+ // If the conformance is conditional and any of the substitutions used to
1926
+ // satisfy the conditions are retroactive, it's retroactive.
1927
+ return forEachConditionalConformance (conformance,
1928
+ [&](Type substType, ProtocolConformanceRef substConf) -> bool {
1929
+ return containsRetroactiveConformance (substConf);
1930
+ });
1931
+ }
1932
+
1909
1933
void ASTMangler::appendRetroactiveConformances (SubstitutionMap subMap,
1910
- GenericSignature sig,
1911
- ModuleDecl *fromModule) {
1934
+ GenericSignature sig) {
1912
1935
if (subMap.empty ()) return ;
1913
1936
1914
1937
unsigned numProtocolRequirements = 0 ;
@@ -1924,14 +1947,18 @@ void ASTMangler::appendRetroactiveConformances(SubstitutionMap subMap,
1924
1947
};
1925
1948
1926
1949
// Ignore abstract conformances.
1927
- if (!conformance.isConcrete ())
1950
+ if (!conformance.isConcrete () && !conformance. isPack () )
1928
1951
continue ;
1929
1952
1930
1953
// Skip non-retroactive conformances.
1931
- if (!containsRetroactiveConformance (conformance. getConcrete (), fromModule ))
1954
+ if (!containsRetroactiveConformance (conformance))
1932
1955
continue ;
1933
1956
1934
- appendConcreteProtocolConformance (conformance.getConcrete (), sig);
1957
+ if (conformance.isConcrete ())
1958
+ appendConcreteProtocolConformance (conformance.getConcrete (), sig);
1959
+ else
1960
+ appendPackProtocolConformance (conformance.getPack (), sig);
1961
+
1935
1962
appendOperator (" g" , Index (numProtocolRequirements));
1936
1963
}
1937
1964
}
@@ -1954,7 +1981,7 @@ void ASTMangler::appendRetroactiveConformances(Type type, GenericSignature sig)
1954
1981
subMap = type->getContextSubstitutionMap (module , nominal);
1955
1982
}
1956
1983
1957
- appendRetroactiveConformances (subMap, sig, module );
1984
+ appendRetroactiveConformances (subMap, sig);
1958
1985
}
1959
1986
1960
1987
void ASTMangler::appendSymbolicExtendedExistentialType (
@@ -1977,11 +2004,7 @@ void ASTMangler::appendSymbolicExtendedExistentialType(
1977
2004
for (auto argType : genInfo.Generalization .getReplacementTypes ())
1978
2005
appendType (argType, sig, forDecl);
1979
2006
1980
- // What module should be used here? The existential isn't anchored
1981
- // to any given module; we should just treat conformances as
1982
- // retroactive if they're "objectively" retroactive.
1983
- appendRetroactiveConformances (genInfo.Generalization , sig,
1984
- /* from module*/ nullptr );
2007
+ appendRetroactiveConformances (genInfo.Generalization , sig);
1985
2008
}
1986
2009
1987
2010
appendOperator (" Xj" );
@@ -2172,7 +2195,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
2172
2195
}
2173
2196
if (auto subs = fn->getInvocationSubstitutions ()) {
2174
2197
appendFlatGenericArgs (subs, sig, forDecl);
2175
- appendRetroactiveConformances (subs, sig, Mod );
2198
+ appendRetroactiveConformances (subs, sig);
2176
2199
}
2177
2200
if (auto subs = fn->getPatternSubstitutions ()) {
2178
2201
appendGenericSignature (subs.getGenericSignature ());
@@ -2181,7 +2204,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
2181
2204
? fn->getInvocationGenericSignature ()
2182
2205
: outerGenericSig;
2183
2206
appendFlatGenericArgs (subs, sig, forDecl);
2184
- appendRetroactiveConformances (subs, sig, Mod );
2207
+ appendRetroactiveConformances (subs, sig);
2185
2208
}
2186
2209
2187
2210
OpArgs.push_back (' _' );
@@ -2217,7 +2240,7 @@ void ASTMangler::appendOpaqueTypeArchetype(ArchetypeType *archetype,
2217
2240
appendOpaqueDeclName (opaqueDecl);
2218
2241
bool isFirstArgList = true ;
2219
2242
appendBoundGenericArgs (opaqueDecl, sig, subs, isFirstArgList, forDecl);
2220
- appendRetroactiveConformances (subs, sig, opaqueDecl-> getParentModule () );
2243
+ appendRetroactiveConformances (subs, sig);
2221
2244
2222
2245
appendOperator (" Qo" , Index (genericParam->getIndex ()));
2223
2246
} else {
@@ -4141,62 +4164,73 @@ void ASTMangler::appendAnyProtocolConformance(
4141
4164
appendDependentProtocolConformance (conformancePath, opaqueSignature);
4142
4165
appendType (conformingType, genericSig);
4143
4166
appendOperator (" HO" );
4144
- } else {
4167
+ } else if (conformance. isConcrete ()) {
4145
4168
appendConcreteProtocolConformance (conformance.getConcrete (), genericSig);
4169
+ } else if (conformance.isPack ()) {
4170
+ appendPackProtocolConformance (conformance.getPack (), genericSig);
4171
+ } else {
4172
+ llvm::errs () << " Bad conformance in mangler: " ;
4173
+ conformance.dump (llvm::errs ());
4174
+ abort ();
4146
4175
}
4147
4176
}
4148
4177
4149
4178
void ASTMangler::appendConcreteProtocolConformance (
4150
4179
const ProtocolConformance *conformance,
4151
4180
GenericSignature sig) {
4152
- auto module = conformance->getDeclContext ()->getParentModule ();
4153
-
4154
4181
// Conforming type.
4155
4182
Type conformingType = conformance->getType ();
4156
4183
if (conformingType->hasArchetype ())
4157
4184
conformingType = conformingType->mapTypeOutOfContext ();
4158
- appendType (conformingType->getCanonicalType ( ), sig);
4185
+ appendType (conformingType->getReducedType (sig ), sig);
4159
4186
4160
4187
// Protocol conformance reference.
4161
4188
appendProtocolConformanceRef (conformance->getRootConformance ());
4162
4189
4163
4190
// Conditional conformance requirements.
4164
4191
bool firstRequirement = true ;
4165
- for (const auto &conditionalReq : conformance->getConditionalRequirements ()) {
4166
- switch (conditionalReq.getKind ()) {
4167
- case RequirementKind::SameShape:
4168
- llvm_unreachable (" Same-shape requirement not supported here" );
4169
- case RequirementKind::Layout:
4170
- case RequirementKind::SameType:
4171
- case RequirementKind::Superclass:
4172
- continue ;
4173
-
4174
- case RequirementKind::Conformance: {
4175
- auto type = conditionalReq.getFirstType ();
4176
- if (type->hasArchetype ())
4177
- type = type->mapTypeOutOfContext ();
4178
- CanType canType = type->getReducedType (sig);
4179
- auto proto = conditionalReq.getProtocolDecl ();
4180
-
4181
- ProtocolConformanceRef conformance;
4182
-
4183
- if (canType->isTypeParameter () || canType->is <OpaqueTypeArchetypeType>()){
4184
- conformance = ProtocolConformanceRef (proto);
4185
- } else {
4186
- conformance = module ->lookupConformance (canType, proto);
4187
- }
4188
- appendAnyProtocolConformance (sig, canType, conformance);
4192
+ forEachConditionalConformance (conformance,
4193
+ [&](Type substType, ProtocolConformanceRef substConf) -> bool {
4194
+ if (substType->hasArchetype ())
4195
+ substType = substType->mapTypeOutOfContext ();
4196
+ CanType canType = substType->getReducedType (sig);
4197
+ appendAnyProtocolConformance (sig, canType, substConf);
4189
4198
appendListSeparator (firstRequirement);
4190
- break ;
4191
- }
4192
- }
4193
- }
4199
+ return false ;
4200
+ });
4201
+
4194
4202
if (firstRequirement)
4195
4203
appendOperator (" y" );
4196
4204
4197
4205
appendOperator (" HC" );
4198
4206
}
4199
4207
4208
+ void ASTMangler::appendPackProtocolConformance (
4209
+ const PackConformance *conformance,
4210
+ GenericSignature sig) {
4211
+ auto conformingType = conformance->getType ();
4212
+ auto patternConformances = conformance->getPatternConformances ();
4213
+ assert (conformingType->getNumElements () == patternConformances.size ());
4214
+
4215
+ if (conformingType->getNumElements () == 0 ) {
4216
+ appendOperator (" y" );
4217
+ } else {
4218
+ bool firstField = true ;
4219
+ for (unsigned i = 0 , e = conformingType->getNumElements (); i < e; ++i) {
4220
+ auto type = conformingType->getElementType (i);
4221
+ auto conf = patternConformances[i];
4222
+
4223
+ if (auto *expansionTy = type->getAs <PackExpansionType>())
4224
+ type = expansionTy->getPatternType ();
4225
+
4226
+ appendAnyProtocolConformance (sig, type->getCanonicalType (), conf);
4227
+ appendListSeparator (firstField);
4228
+ }
4229
+ }
4230
+
4231
+ appendOperator (" HX" );
4232
+ }
4233
+
4200
4234
void ASTMangler::appendOpParamForLayoutConstraint (LayoutConstraint layout) {
4201
4235
assert (layout);
4202
4236
switch (layout->getKind ()) {
0 commit comments