Merge pull request #13364 from slavapestov/fix-default-witness-checking

Fix default witness checking
diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h
index c133755..5031fd8 100644
--- a/include/swift/Subsystems.h
+++ b/include/swift/Subsystems.h
@@ -184,10 +184,6 @@
                            unsigned WarnLongExpressionTypeChecking = 0,
                            unsigned ExpressionTimeoutThreshold = 0);
 
-  /// Once type checking is complete, this walks protocol requirements
-  /// to resolve default witnesses.
-  void finishTypeCheckingFile(SourceFile &SF);
-
   /// Now that we have type-checked an entire module, perform any type
   /// checking that requires the full module, e.g., Objective-C method
   /// override checking.
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index ff0228a..1898ea3 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -651,7 +651,6 @@
       performWholeModuleTypeChecking(SF);
     });
   }
-  forEachFileToTypeCheck([&](SourceFile &SF) { finishTypeCheckingFile(SF); });
 }
 
 void CompilerInstance::performParseOnly(bool EvaluateConditionals) {
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 3eff408..fa26ecc 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -827,7 +827,8 @@
 
     // Build a default witness table if this is a protocol.
     if (auto protocol = dyn_cast<ProtocolDecl>(theType)) {
-      if (!protocol->isObjC())
+      if (!protocol->isObjC() &&
+          !protocol->hasFixedLayout())
         SGM.emitDefaultWitnessTable(protocol);
       return;
     }
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 78c37a2..ab1bd65 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3969,6 +3969,10 @@
       if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
         TC.checkDeclCircularity(nominal);
       }
+      if (auto protocol = dyn_cast<ProtocolDecl>(decl)) {
+        if (!protocol->hasFixedLayout())
+          TC.inferDefaultWitnesses(protocol);
+      }
     }
   }
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index baa636b..6b33061 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -384,6 +384,10 @@
   /// The set of optional adjustments performed on the witness.
   SmallVector<OptionalAdjustment, 2> OptionalAdjustments;
 
+  /// Substitutions mapping the type of the witness to the requirement
+  /// environment.
+  SmallVector<Substitution, 2> WitnessSubstitutions;
+
   /// \brief Determine whether this match is viable.
   bool isViable() const {
     switch(Kind) {
@@ -438,8 +442,6 @@
     llvm_unreachable("Unhandled MatchKind in switch.");
   }
 
-  SmallVector<Substitution, 2> WitnessSubstitutions;
-
   swift::Witness getWitness(ASTContext &ctx) const {
     SmallVector<Substitution, 2> syntheticSubs;
     auto syntheticEnv = ReqEnv->getSyntheticEnvironment();
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index cb30575..e791fe9 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -672,15 +672,6 @@
   }
 }
 
-void swift::finishTypeCheckingFile(SourceFile &SF) {
-  auto &Ctx = SF.getASTContext();
-  TypeChecker TC(Ctx);
-
-  for (auto D : SF.Decls)
-    if (auto PD = dyn_cast<ProtocolDecl>(D))
-      TC.inferDefaultWitnesses(PD);
-}
-
 void swift::performWholeModuleTypeChecking(SourceFile &SF) {
   SharedTimer("performWholeModuleTypeChecking");
   auto &Ctx = SF.getASTContext();
diff --git a/test/SILGen/protocol_resilience.swift b/test/SILGen/protocol_resilience.swift
index 8ece9cc..490e7ab 100644
--- a/test/SILGen/protocol_resilience.swift
+++ b/test/SILGen/protocol_resilience.swift
@@ -254,19 +254,6 @@
   inoutFunc(&OtherConformingType.staticPropertyInExtension)
 }
 
-// Protocol is not public -- make sure default witnesses have the right linkage
-protocol InternalProtocol {
-  func noDefaultF()
-  func defaultG()
-}
-
-extension InternalProtocol {
-
-  // CHECK-LABEL: sil private [transparent] [thunk] @_T019protocol_resilience16InternalProtocolP8defaultGyyF
-  // CHECK: return
-  func defaultG() {}
-}
-
 // CHECK-LABEL: sil_default_witness_table P {
 // CHECK-NEXT: }
 
@@ -328,8 +315,3 @@
 // CHECK-NEXT:   method #ReabstractSelfRefined.callback!setter.1: {{.*}} : @_T019protocol_resilience21ReabstractSelfRefinedP8callbackxxcvs
 // CHECK-NEXT:   method #ReabstractSelfRefined.callback!materializeForSet.1: {{.*}} : @_T019protocol_resilience21ReabstractSelfRefinedP8callbackxxcvm
 // CHECK-NEXT: }
-
-// CHECK-LABEL: sil_default_witness_table hidden InternalProtocol {
-// CHECK-NEXT:   no_default
-// CHECK-NEXT:   method #InternalProtocol.defaultG!1: {{.*}} : @_T019protocol_resilience16InternalProtocolP8defaultGyyF
-// CHECK-NEXT: }
diff --git a/test/SILGen/witness_accessibility.swift b/test/SILGen/witness_accessibility.swift
index 935522d..593c608 100644
--- a/test/SILGen/witness_accessibility.swift
+++ b/test/SILGen/witness_accessibility.swift
@@ -20,9 +20,9 @@
 
 public struct S : R {}
 
-// CHECK-LABEL: sil private @_T021witness_accessibility1R{{.*}}AE18privateRequirementyyF
 // CHECK-LABEL: sil private @_T021witness_accessibility1R{{.*}}E17publicRequirementyyF
 // CHECK-LABEL: sil private @_T021witness_accessibility1R{{.*}}E19internalRequirementyyF
+// CHECK-LABEL: sil private @_T021witness_accessibility1R{{.*}}AE18privateRequirementyyF
 
 // CHECK-LABEL: sil private [transparent] [thunk] @_T021witness_accessibility1SVAA1R{{.*}}dELLP18privateRequirementyyFTW
 // CHECK-LABEL: sil private [transparent] [thunk] @_T021witness_accessibility1SVAA1QA2aDP19internalRequirementyyFTW
diff --git a/test/SILOptimizer/dead_function_elimination.swift b/test/SILOptimizer/dead_function_elimination.swift
index 8a867da..8344eac 100644
--- a/test/SILOptimizer/dead_function_elimination.swift
+++ b/test/SILOptimizer/dead_function_elimination.swift
@@ -216,15 +216,3 @@
 
 // CHECK-TESTING-LABEL: sil_witness_table [serialized] Adopt: Prot
 // CHECK-TESTING: DeadWitness{{.*}}: @{{.*}}DeadWitness
-
-// CHECK-LABEL: sil_default_witness_table hidden Prot
-// CHECK:  no_default
-// CHECK:  no_default
-// CHECK:  method #Prot.aliveDefaultWitness!1: {{.*}} : @{{.*}}aliveDefaultWitness
-// CHECK:  no_default
-
-// CHECK-TESTING-LABEL: sil_default_witness_table Prot
-// CHECK-TESTING:  no_default
-// CHECK-TESTING:  no_default
-// CHECK-TESTING:  method #Prot.aliveDefaultWitness!1: {{.*}} : @{{.*}}aliveDefaultWitness
-// CHECK-TESTING:  method #Prot.DeadDefaultWitness!1: {{.*}} : @{{.*}}DeadDefaultWitness
diff --git a/test/multifile/Inputs/default-witness.swift b/test/multifile/Inputs/default-witness.swift
new file mode 100644
index 0000000..6d0dbd8
--- /dev/null
+++ b/test/multifile/Inputs/default-witness.swift
@@ -0,0 +1,9 @@
+public protocol Node: Source { }
+
+public protocol Source {
+    associatedtype Output
+}
+
+public final class GraphNode<U>: Node {
+    public typealias Output = U
+}
diff --git a/test/multifile/default-witness.swift b/test/multifile/default-witness.swift
new file mode 100644
index 0000000..65f5aae
--- /dev/null
+++ b/test/multifile/default-witness.swift
@@ -0,0 +1,10 @@
+// RUN: %target-swift-frontend -typecheck %S/Inputs/default-witness.swift -primary-file %s -enable-resilience
+
+public protocol GraphType {
+    func insert<U>(_: GraphNode<U>, _: GraphNode<U>)
+}
+
+public extension GraphType {
+    func insert<N: Node>(_: N, _: GraphNode<N.Output>) {}
+}
+