Merge pull request #18697 from slavapestov/minor-irgen-cleanups

Minor IRGen cleanups
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 3c14420..0eb31a7 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -488,7 +488,7 @@
     HasLazyConformances : 1
   );
 
-  SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+2+8+16,
+  SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+8+16,
     /// Whether the \c RequiresClass bit is valid.
     RequiresClassValid : 1,
 
@@ -511,9 +511,6 @@
     /// because they could not be imported from Objective-C).
     HasMissingRequirements : 1,
 
-    /// Whether we are currently computing inherited protocols.
-    ComputingInheritedProtocols : 1,
-
     /// The stage of the circularity check for this protocol.
     Circularity : 2,
 
diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h
index 3f45cd5..e391050 100644
--- a/include/swift/AST/LazyResolver.h
+++ b/include/swift/AST/LazyResolver.h
@@ -72,16 +72,6 @@
   /// considered to be members of the extended type.
   virtual void resolveExtension(ExtensionDecl *ext) = 0;
 
-  using ConformanceConstructionInfo = std::pair<SourceLoc, ProtocolDecl *>;
-  /// Resolve enough of an extension to find which protocols it is declaring
-  /// conformance to.
-  ///
-  /// This can be called to ensure that the "extension Foo: Bar, Baz" part of
-  /// the extension is understood.
-  virtual void resolveExtensionForConformanceConstruction(
-      ExtensionDecl *ext,
-      SmallVectorImpl<ConformanceConstructionInfo> &protocols) = 0;
-
   /// Resolve any implicitly-declared constructors within the given nominal.
   virtual void resolveImplicitConstructors(NominalTypeDecl *nominal) = 0;
 
diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h
index f5c00a5..2341151 100644
--- a/include/swift/AST/NameLookupRequests.h
+++ b/include/swift/AST/NameLookupRequests.h
@@ -184,6 +184,30 @@
   void noteCycleStep(DiagnosticEngine &diags) const;
 };
 
+/// Request the nominal types that occur as the right-hand side of "Self: Foo"
+/// constraints in the "where" clause of a protocol extension.
+class SelfBoundsFromWhereClauseRequest :
+    public SimpleRequest<SelfBoundsFromWhereClauseRequest,
+                         CacheKind::Uncached,
+                         llvm::TinyPtrVector<NominalTypeDecl *>,
+                         ExtensionDecl *> {
+public:
+  using SimpleRequest::SimpleRequest;
+
+private:
+  friend class SimpleRequest;
+
+  // Evaluation.
+  llvm::TinyPtrVector<NominalTypeDecl *> evaluate(Evaluator &evaluator,
+                                                  ExtensionDecl *ext) const;
+
+public:
+  // Cycle handling
+  llvm::TinyPtrVector<NominalTypeDecl *> breakCycle() const { return { }; }
+  void diagnoseCycle(DiagnosticEngine &diags) const;
+  void noteCycleStep(DiagnosticEngine &diags) const;
+};
+
 /// The zone number for name-lookup requests.
 #define SWIFT_NAME_LOOKUP_REQUESTS_TYPEID_ZONE 9
 
diff --git a/include/swift/AST/NameLookupTypeIDZone.def b/include/swift/AST/NameLookupTypeIDZone.def
index e397cac..c3dc4fe 100644
--- a/include/swift/AST/NameLookupTypeIDZone.def
+++ b/include/swift/AST/NameLookupTypeIDZone.def
@@ -18,3 +18,4 @@
 SWIFT_TYPEID(UnderlyingTypeDeclsReferencedRequest)
 SWIFT_TYPEID(SuperclassDeclRequest)
 SWIFT_TYPEID(ExtendedNominalRequest)
+SWIFT_TYPEID(SelfBoundsFromWhereClauseRequest)
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 865f4c3..02edb28 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -2490,31 +2490,6 @@
       }
     }
 
-    /// Check the given list of protocols.
-    void verifyProtocolList(Decl *decl, ArrayRef<ProtocolDecl *> protocols) {
-      PrettyStackTraceDecl debugStack("verifying ProtocolList", decl);
-
-      // Make sure that the protocol list is fully expanded.
-      SmallVector<ProtocolDecl *, 4> nominalProtocols(protocols.begin(),
-                                                      protocols.end());
-      ProtocolType::canonicalizeProtocols(nominalProtocols);
-
-      SmallVector<Type, 4> protocolTypes;
-      for (auto proto : protocols)
-        protocolTypes.push_back(proto->getDeclaredType());
-      auto type = ProtocolCompositionType::get(Ctx, protocolTypes,
-                                               /*HasExplicitAnyObject=*/false);
-      auto layout = type->getExistentialLayout();
-      SmallVector<ProtocolDecl *, 4> canonicalProtocols;
-      for (auto *protoTy : layout.getProtocols())
-        canonicalProtocols.push_back(protoTy->getDecl());
-      if (nominalProtocols != canonicalProtocols) {
-        dumpRef(decl);
-        Out << " doesn't have a complete set of protocols\n";
-        abort();
-      }      
-    }
-
     /// Verify that the given conformance makes sense for the given
     /// type.
     void verifyConformance(Type type, ProtocolConformanceRef conformance) {
@@ -2731,9 +2706,6 @@
     }
 
     void verifyChecked(NominalTypeDecl *nominal) {
-      // Make sure that the protocol list is fully expanded.
-      verifyProtocolList(nominal, nominal->getLocalProtocols());
-
       // Make sure that the protocol conformances are complete.
       // Only do so within the source file of the nominal type,
       // because anywhere else this can trigger new type-check requests.
@@ -2749,9 +2721,6 @@
     }
 
     void verifyChecked(ExtensionDecl *ext) {
-      // Make sure that the protocol list is fully expanded.
-      verifyProtocolList(ext, ext->getLocalProtocols());
-
       // Make sure that the protocol conformances are complete.
       for (auto conformance : ext->getLocalConformances()) {
         verifyConformance(ext, conformance);
diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp
index 64dc773..9234b59 100644
--- a/lib/AST/ConformanceLookupTable.cpp
+++ b/lib/AST/ConformanceLookupTable.cpp
@@ -126,8 +126,7 @@
   return C.Allocate(Bytes, Alignment);
 }
 
-ConformanceLookupTable::ConformanceLookupTable(ASTContext &ctx, 
-                                               LazyResolver *resolver) {
+ConformanceLookupTable::ConformanceLookupTable(ASTContext &ctx) {
   // Register a cleanup with the ASTContext to call the conformance
   // table destructor.
   ctx.addCleanup([this]() {
@@ -139,10 +138,13 @@
   this->~ConformanceLookupTable();
 }
 
+namespace {
+  using ConformanceConstructionInfo = std::pair<SourceLoc, ProtocolDecl *>;
+}
+
 template<typename NominalFunc, typename ExtensionFunc>
 void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
                                             NominalTypeDecl *nominal,
-                                            LazyResolver *resolver,
                                             NominalFunc nominalFunc,
                                             ExtensionFunc extensionFunc) {
   assert(static_cast<unsigned>(stage) < NumConformanceStages &&
@@ -175,15 +177,13 @@
     return;
 
   // Handle the extensions that we have not yet visited.
-  llvm::SetVector<ExtensionDecl *> &delayedExtensionDecls
-    = DelayedExtensionDecls[static_cast<unsigned>(stage)];
   nominal->prepareExtensions();
   while (auto next = lastProcessed.getPointer()
                        ? lastProcessed.getPointer()->NextExtension.getPointer()
                        : nominal->FirstExtension) {
     lastProcessed.setPointer(next);
 
-    SmallVector<LazyResolver::ConformanceConstructionInfo, 2> protocols;
+    SmallVector<ConformanceConstructionInfo, 2> protocols;
 
     // If we have conformances we can load, do so.
     // FIXME: This could be lazier.
@@ -196,42 +196,21 @@
         protocols.push_back({SourceLoc(), conf->getProtocol()});
       }
     } else if (next->getParentSourceFile()) {
-      if (!resolver) {
-        // We have a parsed extension that we can't resolve well enough to
-        // get any information from. Queue it for later.
-        // FIXME: Per the comment on DelayedExtensionDecls, this is insane.
-        delayedExtensionDecls.insert(next);
-        continue;
+      bool anyObject = false;
+      for (const auto &found :
+               getDirectlyInheritedNominalTypeDecls(next, anyObject)) {
+        if (auto proto = dyn_cast<ProtocolDecl>(found.second))
+          protocols.push_back({found.first, proto});
       }
-
-      // Resolve this extension.
-      delayedExtensionDecls.remove(next);
-      resolver->resolveExtensionForConformanceConstruction(next, protocols);
     }
 
     extensionFunc(next, protocols);
   }
-
-  // If we delayed any extension declarations because we didn't have a resolver
-  // then, but we have a resolver now, process them.
-  if (resolver) {
-    while (!delayedExtensionDecls.empty()) {
-      // Remove the last extension declaration.
-      auto ext = delayedExtensionDecls.back();
-      delayedExtensionDecls.remove(ext);
-
-      SmallVector<LazyResolver::ConformanceConstructionInfo, 2> protocols;
-
-      resolver->resolveExtensionForConformanceConstruction(ext, protocols);
-      extensionFunc(ext, protocols);
-    }
-  }
 }
 
 void ConformanceLookupTable::inheritConformances(ClassDecl *classDecl, 
                                                  ClassDecl *superclassDecl,
-                                                 ExtensionDecl *superclassExt,
-                                                 LazyResolver *resolver) {
+                                                 ExtensionDecl *superclassExt) {
   // Local function to return the location of the superclass. This
   // takes a little digging, so compute on first use and cache it.
   SourceLoc superclassLoc;
@@ -285,19 +264,18 @@
 }
 
 void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
-                                               ConformanceStage stage,
-                                               LazyResolver *resolver) {
+                                               ConformanceStage stage) {
   switch (stage) {
   case ConformanceStage::RecordedExplicit:
     // Record all of the explicit conformances.
     forEachInStage(
-        stage, nominal, resolver,
+        stage, nominal,
         [&](NominalTypeDecl *nominal) {
           addInheritedProtocols(nominal,
                                 ConformanceSource::forExplicit(nominal));
         },
         [&](ExtensionDecl *ext,
-            ArrayRef<LazyResolver::ConformanceConstructionInfo> protos) {
+            ArrayRef<ConformanceConstructionInfo> protos) {
           // The extension decl may not be validated, so we can't use
           // its inherited protocols directly.
           auto source = ConformanceSource::forExplicit(ext);
@@ -307,7 +285,7 @@
     break;
 
   case ConformanceStage::Inherited:
-    updateLookupTable(nominal, ConformanceStage::RecordedExplicit, resolver);
+    updateLookupTable(nominal, ConformanceStage::RecordedExplicit);
 
     // For classes, expand implied conformances of the superclass,
     // because an implied conformance in the superclass is considered
@@ -328,8 +306,7 @@
         superclassDecl->prepareConformanceTable();
         superclassDecl->ConformanceTable->updateLookupTable(
           superclassDecl,
-          ConformanceStage::Resolved,
-          resolver);
+          ConformanceStage::Resolved);
         
         // Expand inherited conformances from all superclasses.
         // We may have circular inheritance in ill-formed classes, so keep an
@@ -338,15 +315,14 @@
         
         do {
           forEachInStage(
-              stage, superclassDecl, resolver,
+              stage, superclassDecl,
               [&](NominalTypeDecl *superclass) {
-                inheritConformances(classDecl, superclassDecl, nullptr,
-                                    resolver);
+                inheritConformances(classDecl, superclassDecl, nullptr);
               },
               [&](ExtensionDecl *ext,
-                  ArrayRef<LazyResolver::ConformanceConstructionInfo> protos) {
+                  ArrayRef<ConformanceConstructionInfo> protos) {
                 (void)protos;
-                inheritConformances(classDecl, superclassDecl, ext, resolver);
+                inheritConformances(classDecl, superclassDecl, ext);
               });
           superclassDecl = superclassDecl->getSuperclassDecl();
           if (circularSuperclass)
@@ -361,33 +337,33 @@
   case ConformanceStage::ExpandedImplied:
     // Record explicit conformances and import inherited conformances
     // before expanding.
-    updateLookupTable(nominal, ConformanceStage::Inherited, resolver);
+    updateLookupTable(nominal, ConformanceStage::Inherited);
 
     // Expand inherited conformances.
     forEachInStage(
-        stage, nominal, resolver,
+        stage, nominal,
         [&](NominalTypeDecl *nominal) {
-          expandImpliedConformances(nominal, nominal, resolver);
+          expandImpliedConformances(nominal, nominal);
         },
         [&](ExtensionDecl *ext,
-            ArrayRef<LazyResolver::ConformanceConstructionInfo> protos) {
+            ArrayRef<ConformanceConstructionInfo> protos) {
           (void)protos;
-          expandImpliedConformances(nominal, ext, resolver);
+          expandImpliedConformances(nominal, ext);
         });
     break;
 
   case ConformanceStage::Resolved:
     // Expand inherited conformances so we have the complete set of
     // conformances.
-    updateLookupTable(nominal, ConformanceStage::ExpandedImplied, resolver);
+    updateLookupTable(nominal, ConformanceStage::ExpandedImplied);
     
     /// Determine whether any extensions were added that might require
     /// us to compute conformances again.
     bool anyChanged = false;
-    forEachInStage(stage, nominal, resolver,
+    forEachInStage(stage, nominal,
                    [&](NominalTypeDecl *nominal) { anyChanged = true; },
                    [&](ExtensionDecl *ext,
-                       ArrayRef<LazyResolver::ConformanceConstructionInfo>) {
+                       ArrayRef<ConformanceConstructionInfo>) {
                      anyChanged = true;
                    });
 
@@ -499,8 +475,7 @@
 }
 
 void ConformanceLookupTable::expandImpliedConformances(NominalTypeDecl *nominal,
-                                                       DeclContext *dc, 
-                                                       LazyResolver *resolver) {
+                                                       DeclContext *dc) {
   // Note: recursive type-checking implies that AllConformances
   // may be reallocated during this traversal, so pay the lookup cost
   // during each iteration.
@@ -856,11 +831,6 @@
         ctx.getInheritedConformance(type, inheritedConformance->getConcrete());
   } else {
     // Create or find the normal conformance.
-    if (auto ext = dyn_cast<ExtensionDecl>(conformingDC)) {
-      if (auto resolver = ctx.getLazyResolver())
-        resolver->bindExtension(ext);
-    }
-
     Type conformingType = conformingDC->getDeclaredInterfaceType();
     SourceLoc conformanceLoc
       = conformingNominal == conformingDC
@@ -964,16 +934,15 @@
        ModuleDecl *module, 
        NominalTypeDecl *nominal,
        ProtocolDecl *protocol, 
-       LazyResolver *resolver,
        SmallVectorImpl<ProtocolConformance *> &conformances) {
   // Update to record all explicit and inherited conformances.
-  updateLookupTable(nominal, ConformanceStage::Inherited, resolver);
+  updateLookupTable(nominal, ConformanceStage::Inherited);
 
   // Look for conformances to this protocol.
   auto known = Conformances.find(protocol);
   if (known == Conformances.end()) {
     // If we didn't find anything, expand implied conformances.
-    updateLookupTable(nominal, ConformanceStage::ExpandedImplied, resolver);
+    updateLookupTable(nominal, ConformanceStage::ExpandedImplied);
     known = Conformances.find(protocol);
 
     // We didn't find anything.
@@ -994,14 +963,13 @@
 void ConformanceLookupTable::lookupConformances(
        NominalTypeDecl *nominal,
        DeclContext *dc,
-       LazyResolver *resolver,
        ConformanceLookupKind lookupKind,
        SmallVectorImpl<ProtocolDecl *> *protocols,
        SmallVectorImpl<ProtocolConformance *> *conformances,
        SmallVectorImpl<ConformanceDiagnostic> *diagnostics) {
   // We need to expand all implied conformances before we can find
   // those conformances that pertain to this declaration context.
-  updateLookupTable(nominal, ConformanceStage::ExpandedImplied, resolver);
+  updateLookupTable(nominal, ConformanceStage::ExpandedImplied);
 
   /// Resolve conformances for each of the protocols to which this
   /// declaration may provide a conformance. Only some of these will
@@ -1064,11 +1032,10 @@
 
 void ConformanceLookupTable::getAllProtocols(
        NominalTypeDecl *nominal,
-       LazyResolver *resolver,
        SmallVectorImpl<ProtocolDecl *> &scratch) {
   // We need to expand all implied conformances to find the complete
   // set of protocols to which this nominal type conforms.
-  updateLookupTable(nominal, ConformanceStage::ExpandedImplied, resolver);
+  updateLookupTable(nominal, ConformanceStage::ExpandedImplied);
 
   // Gather all of the protocols.
   for (const auto &conformance : Conformances) {
@@ -1119,11 +1086,10 @@
 
 void ConformanceLookupTable::getAllConformances(
        NominalTypeDecl *nominal,
-       LazyResolver *resolver,
        bool sorted,
        SmallVectorImpl<ProtocolConformance *> &scratch) {
   // We need to expand and resolve all conformances to enumerate them.
-  updateLookupTable(nominal, ConformanceStage::Resolved, resolver);
+  updateLookupTable(nominal, ConformanceStage::Resolved);
 
   // Gather all of the protocols.
   for (const auto &conformance : AllConformances) {
@@ -1154,14 +1120,13 @@
 ConformanceLookupTable::getSatisfiedProtocolRequirementsForMember(
                                                 const ValueDecl *member,
                                                 NominalTypeDecl *nominal,
-                                                LazyResolver *resolver,
                                                 bool sorted) {
   auto It = ConformingDeclMap.find(member);
   if (It != ConformingDeclMap.end())
     return It->second;
 
   SmallVector<ProtocolConformance *, 4> result;
-  getAllConformances(nominal, resolver, sorted, result);
+  getAllConformances(nominal, sorted, result);
 
   auto &reqs = ConformingDeclMap[member];
   if (isa<TypeDecl>(member)) {
@@ -1169,9 +1134,9 @@
       if (conf->isInvalid())
         continue;
 
-      conf->forEachTypeWitness(resolver, [&](const AssociatedTypeDecl *assoc,
-                                             Type type,
-                                             TypeDecl *typeDecl) -> bool {
+      conf->forEachTypeWitness(nullptr, [&](const AssociatedTypeDecl *assoc,
+                                            Type type,
+                                            TypeDecl *typeDecl) -> bool {
         if (typeDecl == member)
           reqs.push_back(const_cast<AssociatedTypeDecl*>(assoc));
         return false;
@@ -1183,8 +1148,8 @@
         continue;
 
       auto normal = conf->getRootNormalConformance();
-      normal->forEachValueWitness(resolver, [&](ValueDecl *req,
-                                                Witness witness) {
+      normal->forEachValueWitness(nullptr,
+                                  [&](ValueDecl *req, Witness witness) {
         if (witness.getDecl() == member)
           reqs.push_back(req);
       });
diff --git a/lib/AST/ConformanceLookupTable.h b/lib/AST/ConformanceLookupTable.h
index cbdf326..bcd3f5c 100644
--- a/lib/AST/ConformanceLookupTable.h
+++ b/lib/AST/ConformanceLookupTable.h
@@ -78,13 +78,6 @@
                      std::array<LastProcessedEntry, NumConformanceStages>>
   LastProcessed;
   
-  /// The list of parsed extension declarations that have been delayed because
-  /// no resolver was available at the time.
-  ///
-  /// FIXME: This is insane. The resolver should be there or we shouldn't
-  /// have parsed extensions.
-  llvm::SetVector<ExtensionDecl *> DelayedExtensionDecls[NumConformanceStages];
-
   struct ConformanceEntry;
 
   /// Describes the "source" of a conformance, indicating where the
@@ -340,8 +333,7 @@
                          ConformanceSource source);
 
   /// Expand the implied conformances for the given DeclContext.
-  void expandImpliedConformances(NominalTypeDecl *nominal, DeclContext *dc,
-                                 LazyResolver *resolver);
+  void expandImpliedConformances(NominalTypeDecl *nominal, DeclContext *dc);
 
   /// A three-way ordering
   enum class Ordering {
@@ -391,7 +383,6 @@
   template<typename NominalFunc, typename ExtensionFunc>
   void forEachInStage(ConformanceStage stage,
                       NominalTypeDecl *nominal,
-                      LazyResolver *resolver,
                       NominalFunc nominalFunc,
                       ExtensionFunc extensionFunc);
 
@@ -409,12 +400,10 @@
   /// on the superclass declaration itself will be inherited.
   void inheritConformances(ClassDecl *classDecl, 
                            ClassDecl *superclassDecl,
-                           ExtensionDecl *superclassExt,
-                           LazyResolver *resolver);
+                           ExtensionDecl *superclassExt);
 
   /// Update a lookup table with conformances from newly-added extensions.
-  void updateLookupTable(NominalTypeDecl *nominal, ConformanceStage stage,
-                         LazyResolver *resolver);
+  void updateLookupTable(NominalTypeDecl *nominal, ConformanceStage stage);
 
   /// Load all of the protocol conformances for the given (serialized)
   /// declaration context.
@@ -423,7 +412,7 @@
 
 public:
   /// Create a new conformance lookup table.
-  ConformanceLookupTable(ASTContext &ctx, LazyResolver *resolver);
+  ConformanceLookupTable(ASTContext &ctx);
 
   /// Destroy the conformance table.
   void destroy();
@@ -445,13 +434,11 @@
   bool lookupConformance(ModuleDecl *module,
                          NominalTypeDecl *nominal,
                          ProtocolDecl *protocol, 
-                         LazyResolver *resolver,
                          SmallVectorImpl<ProtocolConformance *> &conformances);
 
   /// Look for all of the conformances within the given declaration context.
   void lookupConformances(NominalTypeDecl *nominal,
                           DeclContext *dc,
-                          LazyResolver *resolver,
                           ConformanceLookupKind lookupKind,
                           SmallVectorImpl<ProtocolDecl *> *protocols,
                           SmallVectorImpl<ProtocolConformance *> *conformances,
@@ -460,13 +447,11 @@
   /// Retrieve the complete set of protocols to which this nominal
   /// type conforms.
   void getAllProtocols(NominalTypeDecl *nominal,
-                       LazyResolver *resolver,
                        SmallVectorImpl<ProtocolDecl *> &scratch);
 
   /// Retrieve the complete set of protocol conformances for this
   /// nominal type.
   void getAllConformances(NominalTypeDecl *nominal,
-                          LazyResolver *resolver,
                           bool sorted,
                           SmallVectorImpl<ProtocolConformance *> &scratch);
 
@@ -481,7 +466,6 @@
   ArrayRef<ValueDecl *>
   getSatisfiedProtocolRequirementsForMember(const ValueDecl *member,
                                             NominalTypeDecl *nominal,
-                                            LazyResolver *resolver,
                                             bool sorted);
 
   // Only allow allocation of conformance lookup tables using the
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 80e6ba0..1e88287 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3579,7 +3579,6 @@
   Bits.ProtocolDecl.NumRequirementsInSignature = 0;
   Bits.ProtocolDecl.HasMissingRequirements = false;
   Bits.ProtocolDecl.KnownProtocol = 0;
-  Bits.ProtocolDecl.ComputingInheritedProtocols = false;
 }
 
 llvm::TinyPtrVector<ProtocolDecl *>
@@ -3597,8 +3596,6 @@
     }
   }
 
-  // FIXME: ComputingInheritedProtocols is dynamically dead.
-
   return result;
 }
 
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index dbcd15c..6aca43d 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -473,6 +473,68 @@
   llvm_unreachable("Unhandled ASTScopeKind in switch.");
 }
 
+/// Retrieve the set of type declarations that are directly referenced from
+/// the given parsed type representation.
+static DirectlyReferencedTypeDecls
+directReferencesForTypeRepr(Evaluator &evaluator,
+                            ASTContext &ctx, TypeRepr *typeRepr,
+                            DeclContext *dc);
+
+/// Retrieve the set of type declarations that are directly referenced from
+/// the given type.
+static DirectlyReferencedTypeDecls directReferencesForType(Type type);
+
+/// Given a set of type declarations, find all of the nominal type declarations
+/// that they reference, looking through typealiases as appropriate.
+static TinyPtrVector<NominalTypeDecl *>
+resolveTypeDeclsToNominal(Evaluator &evaluator,
+                          ASTContext &ctx,
+                          ArrayRef<TypeDecl *> typeDecls,
+                          SmallVectorImpl<ModuleDecl *> &modulesFound,
+                          bool &anyObject);
+
+TinyPtrVector<NominalTypeDecl *>
+SelfBoundsFromWhereClauseRequest::evaluate(Evaluator &evaluator,
+                                           ExtensionDecl *ext) const {
+  auto proto = ext->getAsProtocolExtensionContext();
+  assert(proto && "Not a protocol extension?");
+
+  ASTContext &ctx = proto->getASTContext();
+  TinyPtrVector<NominalTypeDecl *> result;
+  for (const auto &req : ext->getGenericParams()->getTrailingRequirements()) {
+    // We only care about type constraints.
+    if (req.getKind() != RequirementReprKind::TypeConstraint)
+      continue;
+
+    // The left-hand side of the type constraint must be 'Self'.
+    bool isSelfLHS = false;
+    if (auto typeRepr = req.getSubjectRepr()) {
+      if (auto identTypeRepr = dyn_cast<SimpleIdentTypeRepr>(typeRepr))
+        isSelfLHS = (identTypeRepr->getIdentifier() == ctx.Id_Self);
+    } else if (Type type = req.getSubject()) {
+      isSelfLHS = type->isEqual(proto->getSelfInterfaceType());
+    }
+    if (!isSelfLHS)
+      continue;
+
+    // Resolve the right-hand side.
+    DirectlyReferencedTypeDecls rhsDecls;
+    if (auto typeRepr = req.getConstraintRepr()) {
+      rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, ext);
+    } else if (Type type = req.getConstraint()) {
+      rhsDecls = directReferencesForType(type);
+    }
+
+    SmallVector<ModuleDecl *, 2> modulesFound;
+    bool anyObject = false;
+    auto rhsNominals = resolveTypeDeclsToNominal(evaluator, ctx, rhsDecls,
+                                                 modulesFound, anyObject);
+    result.insert(result.end(), rhsNominals.begin(), rhsNominals.end());
+  }
+
+  return result;
+}
+
 UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
                                      LazyResolver *TypeResolver, SourceLoc Loc,
                                      Options options)
@@ -610,15 +672,16 @@
         if (!nominal) continue;
 
         // Dig out the type we're looking into.
-        // FIXME: We shouldn't need to compute a type to perform this lookup.
-        Type lookupType;
+        SmallVector<NominalTypeDecl *, 2> lookupDecls;
+        lookupDecls.push_back(nominal);
+
+        // For a protocol extension, check whether there are additional
+        // "Self" constraints that can affect name lookup.
         if (isa<ProtocolDecl>(nominal)) {
           if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
-            TypeResolver->bindExtension(ext);
-
-            lookupType = dc->getSelfTypeInContext();
-
-            if (lookupType->hasError()) continue;
+            for (auto bound :
+                    Ctx.evaluator(SelfBoundsFromWhereClauseRequest{ext}))
+              lookupDecls.push_back(bound);
           }
         }
 
@@ -630,10 +693,7 @@
           options |= NL_KnownNonCascadingDependency;
 
         SmallVector<ValueDecl *, 4> lookup;
-        if (lookupType)
-          dc->lookupQualified(lookupType, Name, options, TypeResolver, lookup);
-        else
-          dc->lookupQualified(nominal, Name, options, lookup);
+        dc->lookupQualified(lookupDecls, Name, options, lookup);
 
         auto startIndex = Results.size();
         for (auto result : lookup) {
@@ -687,7 +747,29 @@
         DeclContext *BaseDC = nullptr;
         DeclContext *MetaBaseDC = nullptr;
         GenericParamList *GenericParams = nullptr;
-        Type ExtendedType;
+
+        // Dig out the type we're looking into.
+        SmallVector<NominalTypeDecl *, 2> lookupDecls;
+
+        // Local function to populate the set of lookup declarations from
+        // the given DeclContext.
+        auto populateLookupDeclsFromContext = [&](DeclContext *dc) {
+          auto nominal = dc->getAsNominalTypeOrNominalTypeExtensionContext();
+          if (!nominal)
+            return;
+
+          lookupDecls.push_back(nominal);
+
+          // For a protocol extension, check whether there are additional
+          // "Self" constraints that can affect name lookup.
+          if (isa<ProtocolDecl>(nominal)) {
+            if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
+              for (auto bound :
+                       Ctx.evaluator(SelfBoundsFromWhereClauseRequest{ext}))
+                lookupDecls.push_back(bound);
+            }
+          }
+        };
 
         if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC)) {
           auto *PBD = PBI->getBinding();
@@ -703,7 +785,7 @@
 
             DC = DC->getParent();
 
-            ExtendedType = DC->getSelfTypeInContext();
+            populateLookupDeclsFromContext(DC);
             MetaBaseDC = DC;
             BaseDC = PBI;
           }
@@ -712,7 +794,7 @@
           else if (PBD->getDeclContext()->isTypeContext()) {
             DC = DC->getParent();
 
-            ExtendedType = DC->getSelfTypeInContext();
+            populateLookupDeclsFromContext(DC);
             MetaBaseDC = DC;
             BaseDC = MetaBaseDC;
 
@@ -750,7 +832,7 @@
             isCascadingUse = AFD->isCascadingContextForLookup(false);
 
           if (AFD->getDeclContext()->isTypeContext()) {
-            ExtendedType = AFD->getDeclContext()->getSelfTypeInContext();
+            populateLookupDeclsFromContext(AFD->getDeclContext());
             BaseDC = AFD;
             MetaBaseDC = AFD->getDeclContext();
             DC = DC->getParent();
@@ -796,18 +878,14 @@
             continue;
           }
 
-          if (TypeResolver) {
-            TypeResolver->bindExtension(ED);
-          }
-
-          ExtendedType = ED->getSelfTypeInContext();
+          populateLookupDeclsFromContext(ED);
 
           BaseDC = ED;
           MetaBaseDC = ED;
           if (!isCascadingUse.hasValue())
             isCascadingUse = ED->isCascadingContextForLookup(false);
         } else if (auto *ND = dyn_cast<NominalTypeDecl>(DC)) {
-          ExtendedType = ND->getDeclaredType();
+          populateLookupDeclsFromContext(ND);
           BaseDC = DC;
           MetaBaseDC = DC;
           if (!isCascadingUse.hasValue())
@@ -834,7 +912,7 @@
             return;
         }
 
-        if (BaseDC && ExtendedType && !ExtendedType->hasError()) {
+        if (BaseDC && !lookupDecls.empty()) {
           NLOptions options = baseNLOptions;
           if (isCascadingUse.getValue())
             options |= NL_KnownCascadingDependency;
@@ -842,7 +920,7 @@
             options |= NL_KnownNonCascadingDependency;
 
           SmallVector<ValueDecl *, 4> Lookup;
-          DC->lookupQualified(ExtendedType, Name, options, TypeResolver, Lookup);
+          DC->lookupQualified(lookupDecls, Name, options, Lookup);
           bool FoundAny = false;
           auto startIndex = Results.size();
           for (auto Result : Lookup) {
@@ -2143,8 +2221,6 @@
   return current;
 }
 
-/// Retrieve the set of type declarations that are directly referenced from
-/// the given parsed type representation.
 static DirectlyReferencedTypeDecls
 directReferencesForTypeRepr(Evaluator &evaluator,
                             ASTContext &ctx, TypeRepr *typeRepr,
@@ -2201,8 +2277,6 @@
   }
 }
 
-/// Retrieve the set of type declarations that are directly referenced from
-/// the given type.
 static DirectlyReferencedTypeDecls
 directReferencesForType(Type type) {
   // If it's a typealias, return that.
diff --git a/lib/AST/NameLookupRequests.cpp b/lib/AST/NameLookupRequests.cpp
index 82f38df..d20209d 100644
--- a/lib/AST/NameLookupRequests.cpp
+++ b/lib/AST/NameLookupRequests.cpp
@@ -118,6 +118,20 @@
   diags.diagnose(ext, diag::circular_reference_through);
 }
 
+void SelfBoundsFromWhereClauseRequest::diagnoseCycle(
+                                              DiagnosticEngine &diags) const {
+  // FIXME: Improve this diagnostic.
+  auto ext = std::get<0>(getStorage());
+  diags.diagnose(ext, diag::circular_reference);
+}
+
+void SelfBoundsFromWhereClauseRequest::noteCycleStep(
+                                              DiagnosticEngine &diags) const {
+  auto ext = std::get<0>(getStorage());
+  // FIXME: Customize this further.
+  diags.diagnose(ext, diag::circular_reference_through);
+}
+
 // Define request evaluation functions for each of the name lookup requests.
 static AbstractRequestFunction *nameLookupRequestFunctions[] = {
 #define SWIFT_TYPEID(Name)                                    \
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index 39a5c55..7688944 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -1137,8 +1137,7 @@
 
   auto mutableThis = const_cast<NominalTypeDecl *>(this);
   ASTContext &ctx = getASTContext();
-  auto resolver = ctx.getLazyResolver();
-  ConformanceTable = new (ctx) ConformanceLookupTable(ctx, resolver);
+  ConformanceTable = new (ctx) ConformanceLookupTable(ctx);
   ++NumConformanceLookupTables;
 
   // If this type declaration was not parsed from source code or introduced
@@ -1190,7 +1189,6 @@
            module,
            const_cast<NominalTypeDecl *>(this),
            protocol,
-           getASTContext().getLazyResolver(),
            conformances);
 }
 
@@ -1198,7 +1196,6 @@
   prepareConformanceTable();
   SmallVector<ProtocolDecl *, 2> result;
   ConformanceTable->getAllProtocols(const_cast<NominalTypeDecl *>(this),
-                                    getASTContext().getLazyResolver(),
                                     result);
   return result;
 }
@@ -1209,7 +1206,6 @@
   prepareConformanceTable();
   SmallVector<ProtocolConformance *, 2> result;
   ConformanceTable->getAllConformances(const_cast<NominalTypeDecl *>(this),
-                                       getASTContext().getLazyResolver(),
                                        sorted,
                                        result);
   return result;
@@ -1237,7 +1233,6 @@
   prepareConformanceTable();
   return ConformanceTable->getSatisfiedProtocolRequirementsForMember(member,
                                            const_cast<NominalTypeDecl *>(this),
-                                           getASTContext().getLazyResolver(),
                                            sorted);
 }
 
@@ -1259,7 +1254,6 @@
   nominal->ConformanceTable->lookupConformances(
     nominal,
     const_cast<DeclContext *>(this),
-    getASTContext().getLazyResolver(),
     lookupKind,
     &result,
     nullptr,
@@ -1295,7 +1289,6 @@
   nominal->ConformanceTable->lookupConformances(
     nominal,
     const_cast<DeclContext *>(this),
-    nominal->getASTContext().getLazyResolver(),
     lookupKind,
     nullptr,
     &result,
diff --git a/lib/AST/TypeCheckRequests.cpp b/lib/AST/TypeCheckRequests.cpp
index 48894a0..e915ea6 100644
--- a/lib/AST/TypeCheckRequests.cpp
+++ b/lib/AST/TypeCheckRequests.cpp
@@ -13,6 +13,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/DiagnosticsCommon.h"
 #include "swift/AST/TypeLoc.h"
+#include "swift/AST/TypeRepr.h"
 #include "swift/AST/Types.h"
 
 using namespace swift;
@@ -36,7 +37,10 @@
 
   auto ext = value.get<ExtensionDecl *>();
   out << "extension of ";
-  ext->getAsNominalTypeOrNominalTypeExtensionContext()->dumpRef(out);
+  if (auto typeRepr = ext->getExtendedTypeLoc().getTypeRepr())
+    typeRepr->print(out);
+  else
+    ext->getAsNominalTypeOrNominalTypeExtensionContext()->dumpRef(out);
 }
 
 //----------------------------------------------------------------------------//
diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp
index 6b81673..5dcbe75 100644
--- a/lib/PrintAsObjC/PrintAsObjC.cpp
+++ b/lib/PrintAsObjC/PrintAsObjC.cpp
@@ -932,9 +932,9 @@
       renamedDecl = lookup.getSingleTypeResult();
     } else {
       SmallVector<ValueDecl *, 4> lookupResults;
-      declContext->lookupQualified(declContext->getSelfTypeInContext(),
-                                   renamedDeclName, NL_QualifiedDefault, NULL,
-                                   lookupResults);
+      declContext->lookupQualified(
+        declContext->getAsNominalTypeOrNominalTypeExtensionContext(),
+        renamedDeclName, NL_QualifiedDefault, lookupResults);
       for (auto candidate : lookupResults) {
         if (!shouldInclude(candidate))
           continue;
diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp
index 85b3c6c..a32a927 100644
--- a/lib/SILOptimizer/Utils/CastOptimizer.cpp
+++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp
@@ -353,8 +353,8 @@
   Members = NTD->lookupDirect(M.getASTContext().Id_bridgeToObjectiveC);
   if (Members.empty()) {
     if (NTD->getDeclContext()->lookupQualified(
-            NTD->getDeclaredType(), M.getASTContext().Id_bridgeToObjectiveC,
-            NLOptions::NL_ProtocolMembers, nullptr, FoundMembers)) {
+            NTD, M.getASTContext().Id_bridgeToObjectiveC,
+            NLOptions::NL_ProtocolMembers, FoundMembers)) {
       Members = FoundMembers;
       // Returned members are starting with the most specialized ones.
       // Thus, the first element is what we are looking for.
diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp
index b46b1bb..bbc729d 100644
--- a/lib/Sema/CalleeCandidateInfo.cpp
+++ b/lib/Sema/CalleeCandidateInfo.cpp
@@ -636,9 +636,12 @@
     if (instanceType->mayHaveMembers()) {
       auto ctors = CS.TC.lookupConstructors(
                                             CS.DC, instanceType, NameLookupFlags::IgnoreAccessControl);
-      for (auto ctor : ctors)
+      for (auto ctor : ctors) {
+        if (!ctor.getValueDecl()->hasInterfaceType())
+          CS.getTypeChecker().validateDeclForNameLookup(ctor.getValueDecl());
         if (ctor.getValueDecl()->hasInterfaceType())
           candidates.push_back({ ctor.getValueDecl(), 1 });
+      }
     }
     
     declName = instanceType->getString();
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index 9f0f0be..2550632 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -240,8 +240,9 @@
         // If there's no conformance, we have an existential
         // and we found a member from one of the protocols, and
         // not a class constraint if any.
-        assert(foundInType->isExistentialType());
-        addResult(found);
+        assert(foundInType->isExistentialType() || foundInType->hasError());
+        if (foundInType->isExistentialType())
+          addResult(found);
         return;
       }
 
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 22e469c..b87d95a 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -205,11 +205,6 @@
        TypeResolutionOptions options,
        bool isSpecialized,
        GenericTypeResolver *resolver) {
-  // If we're just resolving the structure, the decl itself is all we need to
-  // know: return the unbound generic type.
-  if (options.contains(TypeResolutionFlags::ResolveStructure))
-    return typeDecl->getDeclaredInterfaceType();
-
   GenericTypeToArchetypeResolver defaultResolver(fromDC);
   if (!resolver)
     resolver = &defaultResolver;
@@ -345,9 +340,6 @@
                                         GenericIdentTypeRepr *generic,
                                         TypeResolutionOptions options,
                                         GenericTypeResolver *resolver) {
-  assert(!options.contains(TypeResolutionFlags::ResolveStructure) &&
-         "should not touch generic arguments when resolving structure");
-
   if (type->hasError()) {
     generic->setInvalid();
     return type;
@@ -432,8 +424,6 @@
   }
 
   // Resolve the types of the generic arguments.
-  assert(!options.contains(TypeResolutionFlags::ResolveStructure) &&
-         "should not touch generic arguments when resolving structure");
   options = adjustOptionsForGenericArgs(options);
 
   SmallVector<Type, 2> args;
@@ -663,8 +653,7 @@
 
   if (type->is<UnboundGenericType>() && !generic &&
       !options.is(TypeResolverContext::TypeAliasDecl) &&
-      !options.contains(TypeResolutionFlags::AllowUnboundGenerics) &&
-      !options.contains(TypeResolutionFlags::ResolveStructure)) {
+      !options.contains(TypeResolutionFlags::AllowUnboundGenerics)) {
     diagnoseUnboundGenericType(TC, type, loc);
     return ErrorType::get(TC.Context);
   }
@@ -675,7 +664,7 @@
                                    loc, cast<AssociatedTypeDecl>(typeDecl));
   }
 
-  if (generic && !options.contains(TypeResolutionFlags::ResolveStructure)) {
+  if (generic) {
     // Apply the generic arguments to the type.
     type = TC.applyGenericArguments(type, loc, fromDC, generic,
                                     options, resolver);
@@ -1126,17 +1115,14 @@
               GenericTypeResolver *resolver) {
   auto maybeApplyGenericArgs = [&](Type memberType) {
     // If there are generic arguments, apply them now.
-    if (!options.contains(TypeResolutionFlags::ResolveStructure)) {
-      if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
-        return TC.applyGenericArguments(memberType, comp->getIdLoc(),
-                                        DC, genComp, options, resolver);
-      }
+    if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
+      return TC.applyGenericArguments(memberType, comp->getIdLoc(),
+                                      DC, genComp, options, resolver);
     }
 
     if (memberType->is<UnboundGenericType>() &&
         !options.is(TypeResolverContext::TypeAliasDecl) &&
-        !options.contains(TypeResolutionFlags::AllowUnboundGenerics) &&
-        !options.contains(TypeResolutionFlags::ResolveStructure)) {
+        !options.contains(TypeResolutionFlags::AllowUnboundGenerics)) {
       diagnoseUnboundGenericType(TC, memberType, comp->getLoc());
       return ErrorType::get(TC.Context);
     }
@@ -1414,10 +1400,6 @@
 bool TypeChecker::validateType(TypeLoc &Loc, DeclContext *DC,
                                TypeResolutionOptions options,
                                GenericTypeResolver *resolver) {
-  // FIXME: Verify that these aren't circular and infinite size.
-  assert(!options.contains(TypeResolutionFlags::ResolveStructure) &&
-         "ResolveStructure does not do full validation");
-
   // If we've already validated this type, don't do so again.
   if (Loc.wasValidated())
     return Loc.isError();
@@ -2624,10 +2606,8 @@
   if (!sliceTy)
     return ErrorType::get(Context);
 
-  if (!options.contains(TypeResolutionFlags::ResolveStructure)) {
-    // Check for _ObjectiveCBridgeable conformances in the element type.
-    useObjectiveCBridgeableConformances(DC, baseTy);
-  }
+  // Check for _ObjectiveCBridgeable conformances in the element type.
+  useObjectiveCBridgeableConformances(DC, baseTy);
 
   return sliceTy;
 }
@@ -2649,21 +2629,19 @@
     // Check the requirements on the generic arguments.
     auto unboundTy = dictDecl->getDeclaredType()->castTo<UnboundGenericType>();
 
-    if (!options.contains(TypeResolutionFlags::ResolveStructure)) {
-      Type args[] = {keyTy, valueTy};
+    Type args[] = {keyTy, valueTy};
 
-      if (!TC.applyUnboundGenericArguments(
-              unboundTy, dictDecl, repr->getStartLoc(), DC, args,
-              Resolver)) {
-        return nullptr;
-      }
-
-      // Check for _ObjectiveCBridgeable conformances in the key and value
-      // types.
-      useObjectiveCBridgeableConformances(DC, keyTy);
-      useObjectiveCBridgeableConformances(DC, valueTy);
+    if (!TC.applyUnboundGenericArguments(
+            unboundTy, dictDecl, repr->getStartLoc(), DC, args,
+            Resolver)) {
+      return nullptr;
     }
 
+    // Check for _ObjectiveCBridgeable conformances in the key and value
+    // types.
+    useObjectiveCBridgeableConformances(DC, keyTy);
+    useObjectiveCBridgeableConformances(DC, valueTy);
+
     return dictTy;
   }
 
@@ -3004,6 +2982,9 @@
       return memberType;
     }
 
+    if (baseTy->is<ErrorType>())
+      return ErrorType::get(memberType);
+
     subs = baseTy->getContextSubstitutionMap(module, member->getDeclContext());
     resultType = memberType.subst(subs, SubstFlags::UseErrorType);
   } else {
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index ce8dd17..b934a2b 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -470,33 +470,6 @@
   ::bindExtensionDecl(ext, *this);
 }
 
-void TypeChecker::resolveExtensionForConformanceConstruction(
-    ExtensionDecl *ext,
-    SmallVectorImpl<ConformanceConstructionInfo> &protocols) {
-  // and the protocols which it inherits from:
-  DependentGenericTypeResolver resolver;
-  TypeResolutionOptions options(TypeResolverContext::GenericSignature);
-  options |= TypeResolutionFlags::AllowUnavailableProtocol;
-  options |= TypeResolutionFlags::ResolveStructure;
-  for (auto &inherited : ext->getInherited()) {
-    // We don't want to have know about any generic params/archetypes, because
-    // that requires knowing a full generic environment for the extension (which
-    // can recur with conformance construction). Furthermore, we only *need* to
-    // resolve the protocol references, which won't involve any archetypes: an
-    // invalid inheritance like `struct Foo<T> {} extension Foo: SomeClass<T>
-    // {}` isn't relevant for conformance construction and is caught elsewhere.
-    auto type = inherited.getType();
-    if (!type)
-      type = resolveType(inherited.getTypeRepr(), ext, options, &resolver);
-
-    if (type && type->isExistentialType()) {
-      auto layout = type->getExistentialLayout();
-      for (auto proto : layout.getProtocols())
-        protocols.push_back({inherited.getLoc(), proto->getDecl()});
-    }
-  }
-}
-
 static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC) {
   unsigned currentFunctionIdx = 0;
   unsigned currentExternalDef = TC.Context.LastCheckedExternalDefinition;
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 87af7fd..d2f2fb6 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1382,9 +1382,6 @@
   virtual void resolveExtension(ExtensionDecl *ext) override {
     validateExtension(ext);
   }
-  virtual void resolveExtensionForConformanceConstruction(
-      ExtensionDecl *ext,
-      SmallVectorImpl<ConformanceConstructionInfo> &protocols) override;
 
   virtual void resolveImplicitConstructors(NominalTypeDecl *nominal) override {
     addImplicitConstructors(nominal);
diff --git a/test/SourceKit/DocSupport/doc_clang_module.swift.response b/test/SourceKit/DocSupport/doc_clang_module.swift.response
index 04710e3..9049ca0 100644
--- a/test/SourceKit/DocSupport/doc_clang_module.swift.response
+++ b/test/SourceKit/DocSupport/doc_clang_module.swift.response
@@ -4685,13 +4685,6 @@
         key.offset: 119,
         key.length: 31,
         key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>rawValue</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.function.constructor,
-            key.name: "init(rawValue:)",
-            key.usr: "s:SY8rawValuexSg03RawB0Qz_tcfc"
-          }
-        ],
         key.entities: [
           {
             key.kind: source.lang.swift.decl.var.local,
@@ -4708,14 +4701,7 @@
         key.usr: "s:So8FooEnum1V8rawValues6UInt32Vvp",
         key.offset: 156,
         key.length: 20,
-        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.var.instance,
-            key.name: "rawValue",
-            key.usr: "s:SY8rawValue03RawB0Qzvp"
-          }
-        ]
+        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>"
       },
       {
         key.kind: source.lang.swift.decl.function.operator.infix,
@@ -4798,13 +4784,6 @@
         key.offset: 357,
         key.length: 31,
         key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>rawValue</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.function.constructor,
-            key.name: "init(rawValue:)",
-            key.usr: "s:SY8rawValuexSg03RawB0Qz_tcfc"
-          }
-        ],
         key.entities: [
           {
             key.kind: source.lang.swift.decl.var.local,
@@ -4821,14 +4800,7 @@
         key.usr: "s:So8FooEnum2V8rawValues6UInt32Vvp",
         key.offset: 394,
         key.length: 20,
-        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.var.instance,
-            key.name: "rawValue",
-            key.usr: "s:SY8rawValue03RawB0Qzvp"
-          }
-        ]
+        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>"
       },
       {
         key.kind: source.lang.swift.decl.function.operator.infix,
@@ -4918,13 +4890,6 @@
         key.offset: 627,
         key.length: 31,
         key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>rawValue</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.function.constructor,
-            key.name: "init(rawValue:)",
-            key.usr: "s:SY8rawValuexSg03RawB0Qz_tcfc"
-          }
-        ],
         key.entities: [
           {
             key.kind: source.lang.swift.decl.var.local,
@@ -4941,14 +4906,7 @@
         key.usr: "s:So8FooEnum3V8rawValues6UInt32Vvp",
         key.offset: 664,
         key.length: 20,
-        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.var.instance,
-            key.name: "rawValue",
-            key.usr: "s:SY8rawValue03RawB0Qzvp"
-          }
-        ]
+        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>"
       },
       {
         key.kind: source.lang.swift.decl.function.operator.infix,
@@ -5085,18 +5043,6 @@
         key.offset: 1055,
         key.length: 28,
         key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>rawValue</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:Si\">Int</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.function.constructor,
-            key.name: "init(rawValue:)",
-            key.usr: "s:s9OptionSetP8rawValuex03RawD0Qz_tcfc"
-          },
-          {
-            key.kind: source.lang.swift.ref.function.constructor,
-            key.name: "init(rawValue:)",
-            key.usr: "s:SY8rawValuexSg03RawB0Qz_tcfc"
-          }
-        ],
         key.entities: [
           {
             key.kind: source.lang.swift.decl.var.local,
@@ -7237,13 +7183,6 @@
         key.offset: 7707,
         key.length: 31,
         key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>rawValue</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.function.constructor,
-            key.name: "init(rawValue:)",
-            key.usr: "s:SY8rawValuexSg03RawB0Qz_tcfc"
-          }
-        ],
         key.entities: [
           {
             key.kind: source.lang.swift.decl.var.local,
@@ -7260,14 +7199,7 @@
         key.usr: "s:So11FooSubEnum1V8rawValues6UInt32Vvp",
         key.offset: 7744,
         key.length: 20,
-        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>",
-        key.conforms: [
-          {
-            key.kind: source.lang.swift.ref.var.instance,
-            key.name: "rawValue",
-            key.usr: "s:SY8rawValue03RawB0Qzvp"
-          }
-        ]
+        key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>"
       },
       {
         key.kind: source.lang.swift.decl.function.operator.infix,
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index c947c77..1463ea6 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -709,8 +709,8 @@
         "Strideable",
         "ExpressibleByIntegerLiteral",
         "FixedWidthInteger",
-        "Decodable",
         "Encodable",
+        "Decodable",
         "Hashable",
         "Equatable",
         "_HasCustomAnyHashableRepresentation",