2828#include " swift/AST/MacroDiscriminatorContext.h"
2929#include " swift/AST/Module.h"
3030#include " swift/AST/Ownership.h"
31+ #include " swift/AST/PackConformance.h"
3132#include " swift/AST/ParameterList.h"
3233#include " swift/AST/PrettyStackTrace.h"
3334#include " swift/AST/ProtocolConformance.h"
@@ -1871,20 +1872,11 @@ static bool isRetroactiveConformance(const RootProtocolConformance *root) {
18711872 return conformance->isRetroactive ();
18721873}
18731874
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 ();
18851879
1886- // If the conformance is conditional and any of the substitutions used to
1887- // satisfy the conditions are retroactive, it's retroactive.
18881880 auto subMap = conformance->getSubstitutionMap ();
18891881 for (auto requirement : rootConformance->getConditionalRequirements ()) {
18901882 if (requirement.getKind () != RequirementKind::Conformance)
@@ -1897,18 +1889,49 @@ static bool containsRetroactiveConformance(
18971889 // for indexing purposes.
18981890 continue ;
18991891 }
1900- if (conformance. isConcrete () &&
1901- containsRetroactiveConformance (conformance. getConcrete (), module )) {
1892+
1893+ if ( fn (requirement. getFirstType (). subst (subMap), conformance))
19021894 return true ;
1903- }
19041895 }
19051896
19061897 return false ;
19071898}
19081899
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+
19091933void ASTMangler::appendRetroactiveConformances (SubstitutionMap subMap,
1910- GenericSignature sig,
1911- ModuleDecl *fromModule) {
1934+ GenericSignature sig) {
19121935 if (subMap.empty ()) return ;
19131936
19141937 unsigned numProtocolRequirements = 0 ;
@@ -1924,14 +1947,18 @@ void ASTMangler::appendRetroactiveConformances(SubstitutionMap subMap,
19241947 };
19251948
19261949 // Ignore abstract conformances.
1927- if (!conformance.isConcrete ())
1950+ if (!conformance.isConcrete () && !conformance. isPack () )
19281951 continue ;
19291952
19301953 // Skip non-retroactive conformances.
1931- if (!containsRetroactiveConformance (conformance. getConcrete (), fromModule ))
1954+ if (!containsRetroactiveConformance (conformance))
19321955 continue ;
19331956
1934- appendConcreteProtocolConformance (conformance.getConcrete (), sig);
1957+ if (conformance.isConcrete ())
1958+ appendConcreteProtocolConformance (conformance.getConcrete (), sig);
1959+ else
1960+ appendPackProtocolConformance (conformance.getPack (), sig);
1961+
19351962 appendOperator (" g" , Index (numProtocolRequirements));
19361963 }
19371964}
@@ -1954,7 +1981,7 @@ void ASTMangler::appendRetroactiveConformances(Type type, GenericSignature sig)
19541981 subMap = type->getContextSubstitutionMap (module , nominal);
19551982 }
19561983
1957- appendRetroactiveConformances (subMap, sig, module );
1984+ appendRetroactiveConformances (subMap, sig);
19581985}
19591986
19601987void ASTMangler::appendSymbolicExtendedExistentialType (
@@ -1977,11 +2004,7 @@ void ASTMangler::appendSymbolicExtendedExistentialType(
19772004 for (auto argType : genInfo.Generalization .getReplacementTypes ())
19782005 appendType (argType, sig, forDecl);
19792006
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);
19852008 }
19862009
19872010 appendOperator (" Xj" );
@@ -2172,7 +2195,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
21722195 }
21732196 if (auto subs = fn->getInvocationSubstitutions ()) {
21742197 appendFlatGenericArgs (subs, sig, forDecl);
2175- appendRetroactiveConformances (subs, sig, Mod );
2198+ appendRetroactiveConformances (subs, sig);
21762199 }
21772200 if (auto subs = fn->getPatternSubstitutions ()) {
21782201 appendGenericSignature (subs.getGenericSignature ());
@@ -2181,7 +2204,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
21812204 ? fn->getInvocationGenericSignature ()
21822205 : outerGenericSig;
21832206 appendFlatGenericArgs (subs, sig, forDecl);
2184- appendRetroactiveConformances (subs, sig, Mod );
2207+ appendRetroactiveConformances (subs, sig);
21852208 }
21862209
21872210 OpArgs.push_back (' _' );
@@ -2217,7 +2240,7 @@ void ASTMangler::appendOpaqueTypeArchetype(ArchetypeType *archetype,
22172240 appendOpaqueDeclName (opaqueDecl);
22182241 bool isFirstArgList = true ;
22192242 appendBoundGenericArgs (opaqueDecl, sig, subs, isFirstArgList, forDecl);
2220- appendRetroactiveConformances (subs, sig, opaqueDecl-> getParentModule () );
2243+ appendRetroactiveConformances (subs, sig);
22212244
22222245 appendOperator (" Qo" , Index (genericParam->getIndex ()));
22232246 } else {
@@ -4141,62 +4164,73 @@ void ASTMangler::appendAnyProtocolConformance(
41414164 appendDependentProtocolConformance (conformancePath, opaqueSignature);
41424165 appendType (conformingType, genericSig);
41434166 appendOperator (" HO" );
4144- } else {
4167+ } else if (conformance. isConcrete ()) {
41454168 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 ();
41464175 }
41474176}
41484177
41494178void ASTMangler::appendConcreteProtocolConformance (
41504179 const ProtocolConformance *conformance,
41514180 GenericSignature sig) {
4152- auto module = conformance->getDeclContext ()->getParentModule ();
4153-
41544181 // Conforming type.
41554182 Type conformingType = conformance->getType ();
41564183 if (conformingType->hasArchetype ())
41574184 conformingType = conformingType->mapTypeOutOfContext ();
4158- appendType (conformingType->getCanonicalType ( ), sig);
4185+ appendType (conformingType->getReducedType (sig ), sig);
41594186
41604187 // Protocol conformance reference.
41614188 appendProtocolConformanceRef (conformance->getRootConformance ());
41624189
41634190 // Conditional conformance requirements.
41644191 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);
41894198 appendListSeparator (firstRequirement);
4190- break ;
4191- }
4192- }
4193- }
4199+ return false ;
4200+ });
4201+
41944202 if (firstRequirement)
41954203 appendOperator (" y" );
41964204
41974205 appendOperator (" HC" );
41984206}
41994207
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+
42004234void ASTMangler::appendOpParamForLayoutConstraint (LayoutConstraint layout) {
42014235 assert (layout);
42024236 switch (layout->getKind ()) {
0 commit comments