SubstitutionMap GenericSignature::getSubstitutionMap(SubstitutionList subs) const { SubstitutionMap result(const_cast<GenericSignature *>(this)); enumeratePairedRequirements( [&](Type depTy, ArrayRef<Requirement> reqts) -> bool { auto sub = subs.front(); subs = subs.slice(1); auto canTy = depTy->getCanonicalType(); if (auto paramTy = dyn_cast<GenericTypeParamType>(canTy)) result.addSubstitution(paramTy, sub.getReplacement()); auto conformances = sub.getConformances(); assert(reqts.size() == conformances.size()); for (unsigned i = 0, e = conformances.size(); i < e; i++) { assert(reqts[i].getSecondType()->getAnyNominal() == conformances[i].getRequirement()); result.addConformance(canTy, conformances[i]); } return false; }); assert(subs.empty() && "did not use all substitutions?!"); result.verify(); return result; }
SubstitutionMap GenericEnvironment:: getSubstitutionMap(SubstitutionList subs) const { SubstitutionMap result; for (auto depTy : getGenericSignature()->getAllDependentTypes()) { // Map the interface type to a context type. auto contextTy = depTy.subst(QueryInterfaceTypeSubstitutions(this), MakeAbstractConformanceForGenericType()); auto sub = subs.front(); subs = subs.slice(1); // Record the replacement type and its conformances. if (auto *archetype = contextTy->getAs<ArchetypeType>()) { result.addSubstitution(CanArchetypeType(archetype), sub.getReplacement()); for (auto conformance : sub.getConformances()) result.addConformance(CanType(archetype), conformance); continue; } // FIXME: getAllDependentTypes() includes generic type parameters that // have been made concrete. assert(contextTy->hasError() || depTy->is<GenericTypeParamType>()); } assert(subs.empty() && "did not use all substitutions?!"); populateParentMap(result); return result; }