diff --git a/include/swift/AST/GenericEnvironment.h b/include/swift/AST/GenericEnvironment.h index aad1fc15ef0..7d5e5b63608 100644 --- a/include/swift/AST/GenericEnvironment.h +++ b/include/swift/AST/GenericEnvironment.h @@ -190,6 +190,16 @@ public: /// Retrieve the UUID for an opened element environment. UUID getOpenedElementUUID() const; + using PackElementBinding = + std::pair; + + /// Retrieve the bindings for the opened pack element archetypes in this + /// generic environment to the pack archetypes that contain them. + /// + /// \param bindings The vector to populate with the pack element bindings. + void getPackElementBindings( + SmallVectorImpl &bindings) const; + /// Create a new, primary generic environment. static GenericEnvironment *forPrimary(GenericSignature signature); diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp index 82778b297a3..0b50c9db17e 100644 --- a/lib/AST/GenericEnvironment.cpp +++ b/lib/AST/GenericEnvironment.cpp @@ -125,6 +125,33 @@ UUID GenericEnvironment::getOpenedElementUUID() const { return getTrailingObjects()->uuid; } +void GenericEnvironment::getPackElementBindings( + SmallVectorImpl &bindings) const { + auto packElements = getGenericSignature().getInnermostGenericParams(); + auto packElementDepth = packElements.front()->getDepth(); + auto elementIt = packElements.begin(); + + // Each parameter pack in the outer generic parameters has + // a corresponding pack element parameter at the innermost + // depth. + for (auto *genericParam : getGenericParams()) { + if (genericParam->getDepth() == packElementDepth) + break; + + if (!genericParam->isParameterPack()) + continue; + + assert(elementIt != packElements.end()); + auto *elementArchetype = + mapTypeIntoContext(*elementIt++)->getAs(); + auto *packArchetype = + mapTypeIntoContext(genericParam)->getAs(); + + assert(elementArchetype && packArchetype); + bindings.emplace_back(elementArchetype, packArchetype); + } +} + GenericEnvironment::GenericEnvironment(GenericSignature signature) : SignatureAndKind(signature, Kind::Primary) {