Merge pull request #16881 from gottesmm/pr-6188306c9a0a4eca1bb3e0d6656f8592fb7caf24

diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h
index dbd1a5d..3009fdc 100644
--- a/include/swift/AST/GenericSignature.h
+++ b/include/swift/AST/GenericSignature.h
@@ -175,16 +175,6 @@
     return Mem;
   }
 
-  /// Build a substitution map for this generic signature by looking up
-  /// substitutions in the given substitution map.
-  SubstitutionMap getSubstitutionMap(SubstitutionMap subs) const;
-
-  /// Build an interface type substitution map from a type substitution function
-  /// and conformance lookup function.
-  SubstitutionMap
-  getSubstitutionMap(TypeSubstitutionFn subs,
-                     LookupConformanceFn lookupConformance) const;
-
   /// Look up a stored conformance in the generic signature. These are formed
   /// from same-type constraints placed on associated types of generic
   /// parameters which have conformance constraints on them.
diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h
index c987e73..dca4f8e 100644
--- a/include/swift/SIL/TypeSubstCloner.h
+++ b/include/swift/SIL/TypeSubstCloner.h
@@ -74,10 +74,11 @@
             // Compute substitutions for the specialized function. These
             // substitutions may be different from the original ones, e.g.
             // there can be less substitutions.
-            RecursiveSubs = AI.getFunction()
-                               ->getLoweredFunctionType()
-                               ->getGenericSignature()
-                               ->getSubstitutionMap(Subs);
+            RecursiveSubs = SubstitutionMap::get(
+              AI.getFunction()
+                ->getLoweredFunctionType()
+                ->getGenericSignature(),
+              Subs);
 
             // Use the new set of substitutions to compute the new
             // substituted callee type.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 387f2aa..efeebf4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4934,8 +4934,9 @@
                                SILField(CanType(genericParam),
                                         /*mutable*/ true));
 
-  SubstitutionMap subMap =
-    singleGenericParamSignature->getSubstitutionMap(
+  auto subMap =
+    SubstitutionMap::get(
+      singleGenericParamSignature,
       [&](SubstitutableType *type) -> Type {
         if (type->isEqual(genericParam)) return boxedType;
 
diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp
index 292f46c..c236498 100644
--- a/lib/AST/GenericEnvironment.cpp
+++ b/lib/AST/GenericEnvironment.cpp
@@ -220,9 +220,9 @@
 
 SubstitutionMap GenericEnvironment::getForwardingSubstitutionMap() const {
   auto *genericSig = getGenericSignature();
-  return genericSig->getSubstitutionMap(
-    QueryInterfaceTypeSubstitutions(this),
-    MakeAbstractConformanceForGenericType());
+  return SubstitutionMap::get(genericSig,
+                              QueryInterfaceTypeSubstitutions(this),
+                              MakeAbstractConformanceForGenericType());
 }
 
 std::pair<Type, ProtocolConformanceRef>
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 104e046..53e7699 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -375,20 +375,6 @@
   return M->lookupConformance(type, proto);
 }
 
-SubstitutionMap
-GenericSignature::getSubstitutionMap(SubstitutionMap subs) const {
-  return SubstitutionMap::get(const_cast<GenericSignature *>(this), subs);
-}
-
-SubstitutionMap
-GenericSignature::
-getSubstitutionMap(TypeSubstitutionFn subs,
-                   LookupConformanceFn lookupConformance) const {
-  return SubstitutionMap::get(const_cast<GenericSignature *>(this),
-                              subs, lookupConformance);
-}
-
-
 bool GenericSignature::requiresClass(Type type) {
   if (!type->isTypeParameter()) return false;
 
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index d1146f3..63bdbfc 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -5461,6 +5461,9 @@
       return Action::Continue;
     }
 
+    if (!ty->isSpecialized())
+      return Action::Continue;
+
     // Infer from generic nominal types.
     auto decl = ty->getAnyNominal();
     if (!decl) return Action::Continue;
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index 02996fc..7fff9f1 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -981,9 +981,8 @@
                == substType->getNominalOrBoundGenericNominal()
              && "substitution mapped to different nominal?!");
 
-      SubstitutionMap subMap;
-      if (auto *genericSig = getGenericSignature())
-        subMap = genericSig->getSubstitutionMap(subs, conformances);
+      auto subMap = SubstitutionMap::get(getGenericSignature(),
+                                         subs, conformances);
 
       return substType->getASTContext()
         .getSpecializedConformance(substType,
diff --git a/lib/AST/RequirementEnvironment.cpp b/lib/AST/RequirementEnvironment.cpp
index a7cd8cd..ec5f1b9 100644
--- a/lib/AST/RequirementEnvironment.cpp
+++ b/lib/AST/RequirementEnvironment.cpp
@@ -86,7 +86,7 @@
   auto selfType = cast<GenericTypeParamType>(
       proto->getSelfInterfaceType()->getCanonicalType());
 
-  reqToSyntheticEnvMap = reqSig->getSubstitutionMap(
+  reqToSyntheticEnvMap = SubstitutionMap::get(reqSig,
     [selfType, substConcreteType, depth, covariantSelf, &ctx]
     (SubstitutableType *type) -> Type {
       // If the conforming type is a class, the protocol 'Self' maps to
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index cdb536c..19afc5b 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -434,7 +434,8 @@
                                        LookupConformanceFn conformances) const {
   if (empty()) return SubstitutionMap();
 
-  return getGenericSignature()->getSubstitutionMap(
+  return get(
+    getGenericSignature(),
     [&](SubstitutableType *type) {
       return Type(type).subst(*this, SubstFlags::UseErrorType)
                .subst(subs, conformances, SubstFlags::UseErrorType);
@@ -455,7 +456,8 @@
                                           ProtocolConformanceRef conformance) {
   auto protocolSelfType = protocol->getSelfInterfaceType();
 
-  return protocol->getGenericSignature()->getSubstitutionMap(
+  return get(
+    protocol->getGenericSignature(),
     [&](SubstitutableType *type) -> Type {
       if (type->isEqual(protocolSelfType))
         return selfType;
@@ -526,7 +528,8 @@
   if (derivedSubs)
     origSubMap = *derivedSubs;
   else if (derivedSig) {
-    origSubMap = derivedSig->getSubstitutionMap(
+    origSubMap = get(
+        derivedSig,
         [](SubstitutableType *type) -> Type { return type; },
         MakeAbstractConformanceForGenericType());
   }
@@ -569,7 +572,8 @@
     return type;
   };
 
-  return genericSig->getSubstitutionMap(
+  return get(
+    genericSig,
     [&](SubstitutableType *type) {
       auto replacement = replaceGenericParameter(type);
       if (replacement)
@@ -586,38 +590,55 @@
 }
 
 void SubstitutionMap::verify() const {
-  // FIXME: Remove the conditional compilation once the substitutions
-  // machinery and GenericSignatureBuilder always generate correct
-  // SubstitutionMaps.
-#if 0 && !defined(NDEBUG)
-  for (auto iter = conformanceMap.begin(), end = conformanceMap.end();
-       iter != end; ++iter) {
-    auto replacement = Type(iter->first).subst(*this, SubstFlags::UseErrorType);
-    if (replacement->isTypeParameter() || replacement->is<ArchetypeType>() ||
-        replacement->isTypeVariableOrMember() ||
-        replacement->is<UnresolvedType>() || replacement->hasError())
+#ifndef NDEBUG
+  if (empty())
+    return;
+
+  unsigned conformanceIndex = 0;
+
+  for (const auto &req : getGenericSignature()->getRequirements()) {
+    if (req.getKind() != RequirementKind::Conformance)
       continue;
-    // Check conformances of a concrete replacement type.
-    for (auto citer = iter->second.begin(), cend = iter->second.end();
-         citer != cend; ++citer) {
-      // An existential type can have an abstract conformance to
-      // AnyObject or an @objc protocol.
-      if (citer->isAbstract() && replacement->isExistentialType()) {
-        auto *proto = citer->getRequirement();
-        assert(proto->isObjC() &&
-               "an existential type can conform only to an "
-               "@objc-protocol");
-        continue;
-      }
-      // All of the conformances should be concrete.
-      if (!citer->isConcrete()) {
-        llvm::dbgs() << "Concrete replacement type:\n";
-        replacement->dump(llvm::dbgs());
+
+    auto substType = req.getFirstType().subst(*this, SubstFlags::UseErrorType);
+    if (substType->isTypeParameter() ||
+        substType->is<ArchetypeType>() ||
+        substType->isTypeVariableOrMember() ||
+        substType->is<UnresolvedType>() ||
+        substType->hasError())
+      continue;
+
+    auto conformance = getConformances()[conformanceIndex];
+
+    // An existential type can have an abstract conformance to
+    // AnyObject or an @objc protocol.
+    if (conformance.isAbstract() &&
+        substType->isExistentialType()) {
+      auto *proto = conformance.getRequirement();
+      if (!proto->isObjC()) {
+        llvm::dbgs() << "Existential type conforms to something:\n";
+        substType->dump();
         llvm::dbgs() << "SubstitutionMap:\n";
         dump(llvm::dbgs());
+        llvm::errs() << "\n";
       }
-      assert(citer->isConcrete() && "Conformance should be concrete");
+
+      assert(proto->isObjC() &&
+             "an existential type can conform only to an "
+             "@objc-protocol");
+      continue;
     }
+    // All of the conformances should be concrete.
+    if (!conformance.isConcrete()) {
+      llvm::dbgs() << "Concrete substType type:\n";
+      substType->dump(llvm::dbgs());
+      llvm::dbgs() << "SubstitutionMap:\n";
+      dump(llvm::dbgs());
+      llvm::errs() << "\n";
+    }
+    assert(conformance.isConcrete() && "Conformance should be concrete");
+
+    ++conformanceIndex;
   }
 #endif
 }
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 308b536..f1e4daf 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -3289,9 +3289,10 @@
   auto *genericSig = dc->getGenericSignatureOfContext();
   if (genericSig == nullptr)
     return SubstitutionMap();
-  return genericSig->getSubstitutionMap(
-      QueryTypeSubstitutionMap{getContextSubstitutions(dc, genericEnv)},
-      LookUpConformanceInModule(module));
+  return SubstitutionMap::get(
+    genericSig,
+    QueryTypeSubstitutionMap{getContextSubstitutions(dc, genericEnv)},
+    LookUpConformanceInModule(module));
 }
 
 TypeSubstitutionMap TypeBase::getMemberSubstitutions(
@@ -3336,7 +3337,8 @@
   if (genericSig == nullptr)
     return SubstitutionMap();
   auto subs = getMemberSubstitutions(member, genericEnv);
-  return genericSig->getSubstitutionMap(
+  return SubstitutionMap::get(
+      genericSig,
       QueryTypeSubstitutionMap{subs},
       LookUpConformanceInModule(module));
 }
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 368ade5..ba28f01 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -1591,7 +1591,8 @@
   }
 
   bool failed = false;
-  SubstitutionMap subMap = genericSig->getSubstitutionMap(
+  auto subMap = SubstitutionMap::get(
+    genericSig,
     [&](SubstitutableType *type) -> Type {
       auto genericParam = dyn_cast<GenericTypeParamType>(type);
       if (!genericParam) return nullptr;
diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp
index cdeda25..a70ccab 100644
--- a/lib/RemoteAST/RemoteAST.cpp
+++ b/lib/RemoteAST/RemoteAST.cpp
@@ -183,7 +183,8 @@
     if (genericParams.size() != args.size())
       return Type();
 
-    auto subMap = genericSig->getSubstitutionMap(
+    auto subMap = SubstitutionMap::get(
+        genericSig,
         [&](SubstitutableType *t) -> Type {
           for (unsigned i = 0, e = genericParams.size(); i < e; ++i) {
             if (t->isEqual(genericParams[i]))
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index fe78eed..680317a 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -2386,14 +2386,12 @@
                                SILField(loweredInterfaceType, isMutable));
   
   // Instantiate the layout with identity substitutions.
-  auto subMap = signature->getSubstitutionMap(
+  auto subMap = SubstitutionMap::get(
+    signature,
     [&](SubstitutableType *type) -> Type {
       return signature->getCanonicalTypeInContext(type);
     },
-    [](Type depTy, Type replacementTy, ProtocolDecl *proto)
-    -> ProtocolConformanceRef {
-      return ProtocolConformanceRef(proto);
-    });
+    MakeAbstractConformanceForGenericType());
 
   auto boxTy = SILBoxType::get(C, layout, subMap);
 #ifndef NDEBUG
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 039fd16..c49dbbc 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -4252,8 +4252,18 @@
   // Emit the raw application.
   auto genericSig =
     fn.getType().castTo<SILFunctionType>()->getGenericSignature();
-  if (genericSig != subs.getGenericSignature()) {
-    subs = genericSig->getSubstitutionMap(subs);
+
+  // When calling a closure that's defined in a generic context but does not
+  // capture any generic parameters, we will have substitutions, but the
+  // function type won't have a generic signature. Drop the substitutions in
+  // this case.
+  if (genericSig == nullptr) {
+    subs = SubstitutionMap();
+
+  // Otherwise, the substitutions should match the generic signature.
+  } else {
+    assert(genericSig->getCanonicalSignature() ==
+           subs.getGenericSignature()->getCanonicalSignature());
   }
 
   SILValue rawDirectResult = emitRawApply(
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 1a6c65d..94b1de0 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -708,7 +708,8 @@
   if (auto bridgeAnything =
         SGF.getASTContext().getBridgeAnythingToObjectiveC(nullptr)) {
     auto *genericSig = bridgeAnything->getGenericSignature();
-    auto subMap = genericSig->getSubstitutionMap(
+    auto subMap = SubstitutionMap::get(
+      genericSig,
       [&](SubstitutableType *t) -> Type {
         return nativeType;
       },
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index e5283e4..7addd5d 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -518,7 +518,8 @@
   SubstitutionMap subMap;
   if (auto *genericEnv = ctor->getGenericEnvironmentOfContext()) {
     auto *genericSig = genericEnv->getGenericSignature();
-    subMap = genericSig->getSubstitutionMap(
+    subMap = SubstitutionMap::get(
+      genericSig,
       [&](SubstitutableType *t) -> Type {
         return genericEnv->mapTypeIntoContext(
           t->castTo<GenericTypeParamType>());
@@ -959,19 +960,16 @@
           // Generate a set of substitutions for the initialization function,
           // whose generic signature is that of the type context, and whose
           // replacement types are the archetypes of the initializer itself.
-          subs = typeGenericSig->getSubstitutionMap(
-                       [&](SubstitutableType *type) {
-                         if (auto gp = type->getAs<GenericTypeParamType>()) {
-                           return genericEnv->mapTypeIntoContext(gp);
-                         }
+          subs = SubstitutionMap::get(
+            typeGenericSig,
+            [&](SubstitutableType *type) {
+              if (auto gp = type->getAs<GenericTypeParamType>()) {
+                return genericEnv->mapTypeIntoContext(gp);
+              }
 
-                         return Type(type);
-                       },
-                       [](CanType dependentType,
-                           Type conformingReplacementType,
-                           ProtocolDecl *conformedProtocol) {
-                         return ProtocolConformanceRef(conformedProtocol);
-                       });
+              return Type(type);
+            },
+            MakeAbstractConformanceForGenericType());
         }
 
         // Get the type of the initialization result, in terms
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index b40c3f2..5b2fa0e 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -3655,13 +3655,13 @@
 
       if (auto genericSig =
               hashTy.castTo<SILFunctionType>()->getGenericSignature()) {
-        hashableSubsMap =
-            genericSig->getSubstitutionMap(
-              [&](SubstitutableType *type) -> Type { return formalTy; },
-              [&](CanType dependentType, Type replacementType,
-                  ProtocolDecl *proto)->Optional<ProtocolConformanceRef> {
-                return hashable;
-              });
+        hashableSubsMap = SubstitutionMap::get(
+          genericSig,
+          [&](SubstitutableType *type) -> Type { return formalTy; },
+          [&](CanType dependentType, Type replacementType,
+              ProtocolDecl *proto)->Optional<ProtocolConformanceRef> {
+            return hashable;
+          });
       }
 
       auto hashWitness = subSGF.B.createWitnessMethod(loc,
@@ -4154,7 +4154,8 @@
   }
 
   auto projectionGenericSig = projectFn->getGenericSignature();
-  auto genericArgsMap = projectionGenericSig->getSubstitutionMap(
+  auto genericArgsMap = SubstitutionMap::get(
+      projectionGenericSig,
       [&](SubstitutableType *type) -> Type {
         auto genericParam = cast<GenericTypeParamType>(type);
         auto index =
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 8414287..e3559a6 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -1722,7 +1722,8 @@
       }
       
       auto projectionGenericSig = projectionFunction->getGenericSignature();
-      auto subMap = projectionGenericSig->getSubstitutionMap(
+      auto subMap = SubstitutionMap::get(
+          projectionGenericSig,
           [&](SubstitutableType *type) -> Type {
             auto genericParam = cast<GenericTypeParamType>(type);
             auto index =
@@ -1782,7 +1783,8 @@
       auto projectFn = C.getProjectKeyPathReadOnly(nullptr);
 
       auto projectionGenericSig = projectFn->getGenericSignature();
-      auto subMap = projectionGenericSig->getSubstitutionMap(
+      auto subMap = SubstitutionMap::get(
+          projectionGenericSig,
           [&](SubstitutableType *type) -> Type {
             auto genericParam = cast<GenericTypeParamType>(type);
             auto index =
diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp
index c728d5e..833e73d 100644
--- a/lib/SILGen/SILGenPattern.cpp
+++ b/lib/SILGen/SILGenPattern.cpp
@@ -2589,7 +2589,8 @@
   auto materializedRawValue = rawValue.materialize(SGF, loc);
 
   auto genericSig = diagnoseFailure->getGenericSignature();
-  auto subs = genericSig->getSubstitutionMap(
+  auto subs = SubstitutionMap::get(
+      genericSig,
       [&](SubstitutableType *type) -> Type {
         auto genericParam = cast<GenericTypeParamType>(type);
         assert(genericParam->getDepth() == 0);
@@ -2631,7 +2632,8 @@
   ManagedValue metatype = SGF.B.createValueMetatype(loc, metatypeType, value);
 
   auto diagnoseSignature = diagnoseFailure->getGenericSignature();
-  auto genericArgsMap = diagnoseSignature->getSubstitutionMap(
+  auto genericArgsMap = SubstitutionMap::get(
+      diagnoseSignature,
       [&](SubstitutableType *type) -> Type { return switchedValueSwiftType; },
       LookUpConformanceInSignature(*diagnoseSignature));
 
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 2eb357a..6ff49d1 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -2693,7 +2693,8 @@
   // archetypes.
   if (auto calleeGenericSig = SGF.F.getLoweredFunctionType()
           ->getGenericSignature()) {
-    contextSubs = calleeGenericSig->getSubstitutionMap(
+    contextSubs = SubstitutionMap::get(
+      calleeGenericSig,
       [&](SubstitutableType *type) -> Type {
         return genericEnv->mapTypeIntoContext(type);
       },
@@ -2701,7 +2702,8 @@
   }
 
   // Calculate substitutions to map interface types to the caller's archetypes.
-  interfaceSubs = genericSig->getSubstitutionMap(
+  interfaceSubs = SubstitutionMap::get(
+    genericSig,
     [&](SubstitutableType *type) -> Type {
       if (type->isEqual(newGenericParam))
         return openedExistential;
diff --git a/lib/SILOptimizer/IPO/EagerSpecializer.cpp b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
index fb60a65..31342ab 100644
--- a/lib/SILOptimizer/IPO/EagerSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
@@ -459,9 +459,10 @@
 
 static SubstitutionMap getSingleSubstititutionMap(SILFunction *F,
                                                   Type Ty) {
-  return F->getGenericEnvironment()->getGenericSignature()->
-    getSubstitutionMap([&](SubstitutableType *type) { return Ty; },
-                       MakeAbstractConformanceForGenericType());
+  return SubstitutionMap::get(
+    F->getGenericEnvironment()->getGenericSignature(),
+    [&](SubstitutableType *type) { return Ty; },
+    MakeAbstractConformanceForGenericType());
 }
 
 void EagerDispatch::emitIsTrivialCheck(SILBasicBlock *FailedTypeCheckBB,
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index 4b0e12d..e619675 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -1178,11 +1178,12 @@
     // Each generic parameter of the callee is mapped to its own
     // archetype.
     SpecializedInterfaceToCallerArchetypeMap =
-        SpecializedGenericSig->getSubstitutionMap(
-            [&](SubstitutableType *type) -> Type {
-              return CalleeGenericEnv->mapTypeIntoContext(type);
-            },
-            LookUpConformanceInSignature(*SpecializedGenericSig));
+      SubstitutionMap::get(
+        SpecializedGenericSig,
+        [&](SubstitutableType *type) -> Type {
+          return CalleeGenericEnv->mapTypeIntoContext(type);
+        },
+        LookUpConformanceInSignature(*SpecializedGenericSig));
   }
 
   GenericSignature *getSpecializedGenericSignature() {
@@ -1243,11 +1244,12 @@
     return;
 
   CallerInterfaceToSpecializedInterfaceMap =
-      CallerGenericSig->getSubstitutionMap(
-          [&](SubstitutableType *type) -> Type {
-            return CallerInterfaceToSpecializedInterfaceMapping.lookup(type);
-          },
-          LookUpConformanceInSignature(*CallerGenericSig));
+    SubstitutionMap::get(
+      CallerGenericSig,
+      [&](SubstitutableType *type) -> Type {
+        return CallerInterfaceToSpecializedInterfaceMapping.lookup(type);
+      },
+      LookUpConformanceInSignature(*CallerGenericSig));
 
   DEBUG(llvm::dbgs() << "\n\nCallerInterfaceToSpecializedInterfaceMap map:\n";
         CallerInterfaceToSpecializedInterfaceMap.dump(llvm::dbgs()));
@@ -1258,20 +1260,21 @@
   // Define a substitution map for re-mapping interface types of
   // the specialized function to contextual types of the caller.
   SpecializedInterfaceToCallerArchetypeMap =
-      SpecializedGenericSig->getSubstitutionMap(
-          [&](SubstitutableType *type) -> Type {
-            DEBUG(llvm::dbgs()
-                      << "Mapping specialized interface type to caller "
-                         "archetype:\n";
-                  llvm::dbgs() << "Interface type: "; type->dump();
-                  llvm::dbgs() << "Archetype: ";
-                  auto Archetype =
-                      SpecializedInterfaceToCallerArchetypeMapping.lookup(type);
-                  if (Archetype) Archetype->dump();
-                  else llvm::dbgs() << "Not found!\n";);
-            return SpecializedInterfaceToCallerArchetypeMapping.lookup(type);
-          },
-          LookUpConformanceInSignature(*SpecializedGenericSig));
+    SubstitutionMap::get(
+      SpecializedGenericSig,
+      [&](SubstitutableType *type) -> Type {
+        DEBUG(llvm::dbgs()
+                << "Mapping specialized interface type to caller "
+                   "archetype:\n";
+              llvm::dbgs() << "Interface type: "; type->dump();
+              llvm::dbgs() << "Archetype: ";
+              auto Archetype =
+                  SpecializedInterfaceToCallerArchetypeMapping.lookup(type);
+              if (Archetype) Archetype->dump();
+              else llvm::dbgs() << "Not found!\n";);
+        return SpecializedInterfaceToCallerArchetypeMapping.lookup(type);
+      },
+      LookUpConformanceInSignature(*SpecializedGenericSig));
   DEBUG(llvm::dbgs() << "\n\nSpecializedInterfaceToCallerArchetypeMap map:\n";
         SpecializedInterfaceToCallerArchetypeMap.dump(llvm::dbgs()));
 }
@@ -1279,11 +1282,12 @@
 void FunctionSignaturePartialSpecializer::
     computeCalleeInterfaceToSpecializedInterfaceMap() {
   CalleeInterfaceToSpecializedInterfaceMap =
-      CalleeGenericSig->getSubstitutionMap(
-          [&](SubstitutableType *type) -> Type {
-            return CalleeInterfaceToSpecializedInterfaceMapping.lookup(type);
-          },
-          LookUpConformanceInSignature(*CalleeGenericSig));
+    SubstitutionMap::get(
+      CalleeGenericSig,
+      [&](SubstitutableType *type) -> Type {
+        return CalleeInterfaceToSpecializedInterfaceMapping.lookup(type);
+      },
+      LookUpConformanceInSignature(*CalleeGenericSig));
 
   DEBUG(llvm::dbgs() << "\n\nCalleeInterfaceToSpecializedInterfaceMap:\n";
         CalleeInterfaceToSpecializedInterfaceMap.dump(llvm::dbgs()));
@@ -1485,18 +1489,19 @@
 }
 
 SubstitutionMap FunctionSignaturePartialSpecializer::computeClonerParamSubs() {
-  return CalleeGenericSig->getSubstitutionMap(
-      [&](SubstitutableType *type) -> Type {
-        DEBUG(llvm::dbgs() << "\ngetSubstitution for ClonerParamSubs:\n"
-                           << Type(type) << "\n"
-                           << "in generic signature:\n";
-              CalleeGenericSig->dump());
-        auto SpecializedInterfaceTy =
-            Type(type).subst(CalleeInterfaceToSpecializedInterfaceMap);
-        return SpecializedGenericEnv->mapTypeIntoContext(
-            SpecializedInterfaceTy);
-      },
-      LookUpConformanceInSignature(*SpecializedGenericSig));
+  return SubstitutionMap::get(
+    CalleeGenericSig,
+    [&](SubstitutableType *type) -> Type {
+      DEBUG(llvm::dbgs() << "\ngetSubstitution for ClonerParamSubs:\n"
+                         << Type(type) << "\n"
+                         << "in generic signature:\n";
+            CalleeGenericSig->dump());
+      auto SpecializedInterfaceTy =
+          Type(type).subst(CalleeInterfaceToSpecializedInterfaceMap);
+      return SpecializedGenericEnv->mapTypeIntoContext(
+          SpecializedInterfaceTy);
+    },
+    LookUpConformanceInSignature(*SpecializedGenericSig));
 }
 
 SubstitutionMap FunctionSignaturePartialSpecializer::getCallerParamSubs() {
@@ -1505,17 +1510,18 @@
 
 void FunctionSignaturePartialSpecializer::computeCallerInterfaceSubs(
     SubstitutionMap &CallerInterfaceSubs) {
-  CallerInterfaceSubs = CalleeGenericSig->getSubstitutionMap(
-      [&](SubstitutableType *type) -> Type {
-        // First, map callee's interface type to specialized interface type.
-        auto Ty = Type(type).subst(CalleeInterfaceToSpecializedInterfaceMap);
-        Type SpecializedInterfaceTy =
-          SpecializedGenericEnv->mapTypeIntoContext(Ty)
-            ->mapTypeOutOfContext();
-        assert(!SpecializedInterfaceTy->hasError());
-        return SpecializedInterfaceTy;
-      },
-      LookUpConformanceInSignature(*CalleeGenericSig));
+  CallerInterfaceSubs = SubstitutionMap::get(
+    CalleeGenericSig,
+    [&](SubstitutableType *type) -> Type {
+      // First, map callee's interface type to specialized interface type.
+      auto Ty = Type(type).subst(CalleeInterfaceToSpecializedInterfaceMap);
+      Type SpecializedInterfaceTy =
+        SpecializedGenericEnv->mapTypeIntoContext(Ty)
+          ->mapTypeOutOfContext();
+      assert(!SpecializedInterfaceTy->hasError());
+      return SpecializedInterfaceTy;
+    },
+    LookUpConformanceInSignature(*CalleeGenericSig));
 
   DEBUG(llvm::dbgs() << "\n\nCallerInterfaceSubs map:\n";
         CallerInterfaceSubs.dump(llvm::dbgs()));
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 1674ec3..3818146 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -95,8 +95,9 @@
                                   ConformanceCheckFlags::Used));
   };
 
-  return sig->getSubstitutionMap(QueryTypeSubstitutionMap{subs},
-                                 lookupConformanceFn);
+  return SubstitutionMap::get(sig,
+                              QueryTypeSubstitutionMap{subs},
+                              lookupConformanceFn);
 }
 
 /// \brief Find a particular named function witness for a type that conforms to
@@ -1824,7 +1825,8 @@
       // so we need to form substitutions and compute the resulting type.
       auto genericSig = fn->getGenericSignature();
 
-      auto subMap = genericSig->getSubstitutionMap(
+      auto subMap = SubstitutionMap::get(
+        genericSig,
         [&](SubstitutableType *type) -> Type {
           assert(type->isEqual(genericSig->getGenericParams()[0]));
           return valueType;
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 9b51a89..eefdc0c 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -2805,10 +2805,7 @@
       types[origType] = replacement;
       return replacement;
     },
-    [&](CanType origType, Type substType, ProtocolDecl *conformedProtocol)
-      -> Optional<ProtocolConformanceRef> {
-      return ProtocolConformanceRef(conformedProtocol);
-    });
+    MakeAbstractConformanceForGenericType());
 }
 
 bool TypeChecker::typesSatisfyConstraint(Type type1, Type type2,
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index e1f3f93..4e0b27c 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -8294,15 +8294,12 @@
     auto typealiasSig = typealias->getGenericSignature();
     SubstitutionMap subMap;
     if (typealiasSig) {
-      subMap = typealiasSig->getSubstitutionMap(
-                              [](SubstitutableType *type) -> Type {
-                                return Type(type);
-                              },
-                              [](CanType dependentType,
-                                 Type replacementType,
-                                 ProtocolDecl *proto) {
-                                return ProtocolConformanceRef(proto);
-                              });
+      subMap = SubstitutionMap::get(
+          typealiasSig,
+          [](SubstitutableType *type) -> Type {
+            return Type(type);
+          },
+          MakeAbstractConformanceForGenericType());
 
       mustInferRequirements = true;
     }
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 3b23afd..0a1fc60 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -644,10 +644,11 @@
   Type parentType = unboundType->getParent();
   if (typealias && (!parentType || !parentType->isAnyExistentialType())) {
     auto genericSig = typealias->getGenericSignature();
-    auto subMap = genericSig->getSubstitutionMap(QueryTypeSubstitutionMap{subs},
-                                                 LookUpConformance(*this, dc));
+    auto subMap = SubstitutionMap::get(genericSig,
+                                       QueryTypeSubstitutionMap{subs},
+                                       LookUpConformance(*this, dc));
     resultType = NameAliasType::get(typealias, parentType,
-                                         subMap, resultType);
+                                    subMap, resultType);
   }
 
   if (isa<NominalTypeDecl>(decl) && resultType) {
@@ -2337,7 +2338,8 @@
     }
     
     bool ok = true;
-    subMap = genericSig->getSubstitutionMap(
+    subMap = SubstitutionMap::get(
+      genericSig,
       QueryTypeSubstitutionMap{genericArgMap},
       [&](CanType depTy, Type replacement, ProtocolDecl *proto)
       -> ProtocolConformanceRef {