Merge pull request #6881 from practicalswift/swiftc-28652-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc

diff --git a/include/swift/AST/SubstitutionMap.h b/include/swift/AST/SubstitutionMap.h
index 637206e..971d2f6 100644
--- a/include/swift/AST/SubstitutionMap.h
+++ b/include/swift/AST/SubstitutionMap.h
@@ -43,7 +43,7 @@
   using ParentType = std::pair<CanType, AssociatedTypeDecl *>;
 
   llvm::DenseMap<SubstitutableType *, Type> subMap;
-  llvm::DenseMap<TypeBase *, ArrayRef<ProtocolConformanceRef>> conformanceMap;
+  llvm::DenseMap<TypeBase *, SmallVector<ProtocolConformanceRef, 1>> conformanceMap;
   llvm::DenseMap<TypeBase *, SmallVector<ParentType, 1>> parentMap;
 
   Optional<ProtocolConformanceRef>
@@ -66,7 +66,7 @@
 
   void addSubstitution(CanSubstitutableType type, Type replacement);
 
-  void addConformances(CanType type, ArrayRef<ProtocolConformanceRef> conformances);
+  void addConformance(CanType type, ProtocolConformanceRef conformance);
 
   void addParent(CanType type, CanType parent,
                  AssociatedTypeDecl *assocType);
diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp
index 13d5ea3..78180b3 100644
--- a/lib/AST/GenericEnvironment.cpp
+++ b/lib/AST/GenericEnvironment.cpp
@@ -357,7 +357,8 @@
     // Record the replacement type and its conformances.
     if (auto *archetype = contextTy->getAs<ArchetypeType>()) {
       result.addSubstitution(CanArchetypeType(archetype), sub.getReplacement());
-      result.addConformances(CanType(archetype), sub.getConformances());
+      for (auto conformance : sub.getConformances())
+        result.addConformance(CanType(archetype), conformance);
       continue;
     }
 
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 1540519..c66c7f9 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -313,11 +313,11 @@
     subs = subs.slice(1);
 
     auto canTy = depTy->getCanonicalType();
-    if (isa<SubstitutableType>(canTy)) {
+    if (isa<SubstitutableType>(canTy))
       result.addSubstitution(cast<SubstitutableType>(canTy),
                              sub.getReplacement());
-    }
-    result.addConformances(canTy, sub.getConformances());
+    for (auto conformance : sub.getConformances())
+      result.addConformance(canTy, conformance);
   }
 
   for (auto reqt : getRequirements()) {
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index 9a5e48c..3c33e17 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -97,15 +97,8 @@
 }
 
 void SubstitutionMap::
-addConformances(CanType type, ArrayRef<ProtocolConformanceRef> conformances) {
-  if (conformances.empty())
-    return;
-
-  auto result = conformanceMap.insert(
-      std::make_pair(type.getPointer(), conformances));
-  assert(result.second ||
-         result.first->getSecond().size() == conformances.size());
-  (void) result;
+addConformance(CanType type, ProtocolConformanceRef conformance) {
+  conformanceMap[type.getPointer()].push_back(conformance);
 }
 
 ArrayRef<ProtocolConformanceRef> SubstitutionMap::
@@ -172,8 +165,6 @@
 
   // Map the innermost generic parameters of the derived function to
   // the base.
-  auto &ctx = baseClass->getASTContext();
-
   auto baseParams = baseSig->getInnermostGenericParams();
   if (baseParams.back()->getDepth() >= minDepth) {
     assert(derivedSig);
@@ -203,21 +194,17 @@
         auto canTy = t->getCanonicalType();
 
         if (isRootedInInnermostParameter(t)) {
-          auto conformances =
-              ctx.AllocateUninitialized<ProtocolConformanceRef>(
-                  reqs.size());
           for (unsigned i = 0, e = reqs.size(); i < e; i++) {
             auto reqt = reqs[i];
             assert(reqt.getKind() == RequirementKind::Conformance);
             auto *proto = reqt.getSecondType()
                 ->castTo<ProtocolType>()->getDecl();
             if (derivedSubs)
-              conformances[i] = *derivedSubs->lookupConformance(canTy, proto);
+              subMap.addConformance(canTy, *derivedSubs->lookupConformance(
+                                                                 canTy, proto));
             else
-              conformances[i] = ProtocolConformanceRef(proto);
+              subMap.addConformance(canTy, ProtocolConformanceRef(proto));
           }
-
-          subMap.addConformances(canTy, conformances);
         }
 
         return false;
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index 2d8f5bc..a8497f4 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -1776,9 +1776,7 @@
       specialized = ctx.getSpecializedConformance(concreteTy, conformance,
                                                   concreteSubs);
 
-    SmallVector<ProtocolConformanceRef, 1> conformances;
-    conformances.push_back(ProtocolConformanceRef(specialized));
-    reqtSubs.addConformances(selfTy, ctx.AllocateCopy(conformances));
+    reqtSubs.addConformance(selfTy, ProtocolConformanceRef(specialized));
 
     auto input = reqtOrigTy->getInput().subst(reqtSubs)->getCanonicalType();
     auto result = reqtOrigTy->getResult().subst(reqtSubs)->getCanonicalType();
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index ebb1b5d..4a1e863 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -2456,18 +2456,6 @@
       [&](Type depTy, ArrayRef<Requirement> reqs) -> bool {
     auto canTy = depTy->getCanonicalType();
 
-    // Add abstract conformances.
-    auto conformances =
-        ctx.AllocateUninitialized<ProtocolConformanceRef>(
-            reqs.size());
-    for (unsigned i = 0, e = reqs.size(); i < e; i++) {
-      auto reqt = reqs[i];
-      assert(reqt.getKind() == RequirementKind::Conformance);
-      auto *proto = reqt.getSecondType()
-          ->castTo<ProtocolType>()->getDecl();
-      conformances[i] = ProtocolConformanceRef(proto);
-    }
-
     ArchetypeType *oldArchetype;
     // The opened existential archetype maps to the new generic parameter's
     // archetype.
@@ -2484,11 +2472,19 @@
 
     if (isa<SubstitutableType>(canTy)) {
       interfaceSubs.addSubstitution(cast<SubstitutableType>(canTy),
-                                  oldArchetype);
+                                    oldArchetype);
     }
 
-    contextSubs.addConformances(CanType(oldArchetype), conformances);
-    interfaceSubs.addConformances(canTy, conformances);
+    // Add abstract conformances.
+    for (unsigned i = 0, e = reqs.size(); i < e; i++) {
+      auto reqt = reqs[i];
+      assert(reqt.getKind() == RequirementKind::Conformance);
+      auto *proto = reqt.getSecondType()
+          ->castTo<ProtocolType>()->getDecl();
+      auto conformance = ProtocolConformanceRef(proto);
+      contextSubs.addConformance(CanType(oldArchetype), conformance);
+      interfaceSubs.addConformance(canTy, conformance);
+    }
 
     return false;
   });
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index dfcab64..e26f83d 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -714,7 +714,7 @@
   } else {
     SubstitutionMap Subs;
     Subs.addSubstitution(CanArchetypeType(OpenedArchetype), ConcreteType);
-    Subs.addConformances(CanType(OpenedArchetype), Conformance);
+    Subs.addConformance(CanType(OpenedArchetype), Conformance);
     NewSubstCalleeType = SubstCalleeType.subst(AI.getModule(), Subs);
   }
 
diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp
index 84f56ad..06fc259 100644
--- a/lib/SILOptimizer/Utils/Devirtualize.cpp
+++ b/lib/SILOptimizer/Utils/Devirtualize.cpp
@@ -471,7 +471,9 @@
         subMap.addSubstitution(cast<SubstitutableType>(canTy),
                                sub.getReplacement());
       }
-      subMap.addConformances(canTy, sub.getConformances());
+
+      for (auto conformance : sub.getConformances())
+        subMap.addConformance(canTy, conformance);
     }
     assert(origSubs.empty());
   }
@@ -849,7 +851,8 @@
     auto gp = cast<GenericTypeParamType>(witnessThunkSig->getGenericParams()
                                                  .front()->getCanonicalType());
     subMap.addSubstitution(gp, origSubs.front().getReplacement());
-    subMap.addConformances(gp, origSubs.front().getConformances());
+    for (auto conformance : origSubs.front().getConformances())
+      subMap.addConformance(gp, conformance);
 
     // For default witnesses, innermost generic parameters are always at
     // depth 1.
@@ -916,7 +919,8 @@
         subMap.addSubstitution(cast<SubstitutableType>(canTy),
                                sub.getReplacement());
       }
-      subMap.addConformances(canTy, sub.getConformances());
+      for (auto conformance : sub.getConformances())
+        subMap.addConformance(canTy, conformance);
     }
     assert(subs.empty() && "Did not consume all substitutions");
   }
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index c2a30cc..01ea775 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -1445,26 +1445,11 @@
   }
 
   // Capture the conformances needed for the substitution map.
-  CanType currentType;
-  SmallVector<ProtocolConformanceRef, 4> currentConformances;
-  auto flushConformances = [&] {
-    subMap.addConformances(currentType,
-                           TC.Context.AllocateCopy(currentConformances));
-    currentConformances.clear();
-  };
-
   for (const auto &req : genericSig->getRequirements()) {
-    // If we're on to a new dependent type, flush the conformances gathered
-    // thus far.
-    CanType canFirstType = req.getFirstType()->getCanonicalType();
-    if (canFirstType != currentType) {
-      if (currentType) flushConformances();
-      currentType = canFirstType;
-    }
-
     switch (req.getKind()) {
     case RequirementKind::Conformance: {
       // Get the conformance and record it.
+      auto origType = req.getFirstType()->getCanonicalType();
       auto firstType = req.getFirstType().subst(subMap);
       auto protoType = req.getSecondType()->castTo<ProtocolType>();
       auto conformance =
@@ -1481,7 +1466,7 @@
         return;
       }
 
-      currentConformances.push_back(*conformance);
+      subMap.addConformance(origType, *conformance);
       break;
     }
     case RequirementKind::Superclass: {
@@ -1514,7 +1499,6 @@
     }
     }
   }
-  if (currentType) flushConformances();
 
   // Compute the substitutions.
   SmallVector<Substitution, 4> substitutions;
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 39608ea..af8dd68 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1009,11 +1009,11 @@
   {
     SmallVector<ProtocolConformanceRef, 1> conformances;
     if (specialized)
-      conformances.push_back(ProtocolConformanceRef(specialized));
+      reqToSyntheticEnvMap.addConformance(
+          selfType, ProtocolConformanceRef(specialized));
     else
-      conformances.push_back(ProtocolConformanceRef(proto));
-    reqToSyntheticEnvMap.addConformances(selfType,
-                                         ctx.AllocateCopy(conformances));
+      reqToSyntheticEnvMap.addConformance(
+          selfType, ProtocolConformanceRef(proto));
   }
 
   // Construct an archetype builder by collecting the constraints from the
@@ -1067,11 +1067,11 @@
     if (auto archetypeType
           = reqEnv->mapTypeIntoContext(genericParam)->getAs<ArchetypeType>()) {
       // Add substitutions.
-      SmallVector<ProtocolConformanceRef, 1> conformances;
-      for (auto proto : archetypeType->getConformsTo())
-        conformances.push_back(ProtocolConformanceRef(proto));
-      reqToSyntheticEnvMap.addConformances(genericParam->getCanonicalType(),
-                                           ctx.AllocateCopy(conformances));
+      for (auto proto : archetypeType->getConformsTo()) {
+        reqToSyntheticEnvMap.addConformance(
+            genericParam->getCanonicalType(),
+            ProtocolConformanceRef(proto));
+      }
     }
   }
 
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index c5b4705..92b1f0c 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -4335,12 +4335,10 @@
         reqToSyntheticMap.addSubstitution(canonicalGP, concreteTy);
 
         if (unsigned numConformances = *rawIDIter++) {
-          SmallVector<ProtocolConformanceRef, 2> conformances;
           while (numConformances--) {
-            conformances.push_back(readConformance(DeclTypeCursor));
+            reqToSyntheticMap.addConformance(
+                canonicalGP, readConformance(DeclTypeCursor));
           }
-          reqToSyntheticMap.addConformances(canonicalGP,
-                                            ctx.AllocateCopy(conformances));
         }
       }
     }