Merge pull request #7233 from rudkx/fix-rdar30311052-3.1

[Sema] Penalize conversions to Any.
diff --git a/include/swift/AST/AnyFunctionRef.h b/include/swift/AST/AnyFunctionRef.h
index c2e1a90..2d5e1fb 100644
--- a/include/swift/AST/AnyFunctionRef.h
+++ b/include/swift/AST/AnyFunctionRef.h
@@ -176,6 +176,16 @@
     }
     llvm_unreachable("unexpected AnyFunctionRef representation");
   }
+
+  GenericSignature *getGenericSignature() const {
+    if (auto afd = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
+      return afd->getGenericSignature();
+    }
+    if (auto ce = TheFunction.dyn_cast<AbstractClosureExpr *>()) {
+      return ce->getGenericSignatureOfContext();
+    }
+    llvm_unreachable("unexpected AnyFunctionRef representation");
+  }
 };
 #if SWIFT_COMPILER_IS_MSVC
 #pragma warning(pop)
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index d788a4a..32389f5 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -23,6 +23,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/DiagnosticsSIL.h"
 #include "swift/AST/ForeignErrorConvention.h"
+#include "swift/AST/GenericEnvironment.h"
 #include "swift/Basic/Fallthrough.h"
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/AST/Attr.h"
@@ -742,9 +743,17 @@
   // from the function to which the argument is attached.
   if (constant && !constant->isDefaultArgGenerator())
   if (auto function = constant->getAnyFunctionRef()) {
-    auto getCanonicalType = [&](Type t) -> CanType {
-      if (genericSig)
-        return genericSig->getCanonicalTypeInContext(t, *M.getSwiftModule());
+    // NB: The generic signature may be elided from the lowered function type
+    // if the function is in a fully-specialized context, but we still need to
+    // canonicalize references to the generic parameters that may appear in
+    // non-canonical types in that context. We need the original generic
+    // signature from the AST for that.
+    auto origGenericSig
+      = function->getGenericSignature();
+    auto getCanonicalType = [origGenericSig, &M](Type t) -> CanType {
+      if (origGenericSig)
+        return origGenericSig->getCanonicalTypeInContext(t,
+                                                         *M.getSwiftModule());
       return t->getCanonicalType();
     };
 
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 1c735b8..0803d3e 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -408,6 +408,11 @@
                              ArrayRef<SILValue> Args, bool isNonThrowing,
                              SILFunction &F,
                              SILOpenedArchetypesState &OpenedArchetypes) {
+  if (!F.getModule().Types.getCurGenericContext())
+    assert(Callee->getType().castTo<SILFunctionType>()
+                 ->substGenericArgs(F.getModule(), Subs)
+           == SubstCalleeTy.getSwiftRValueType());
+                                  
   SmallVector<SILValue, 32> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
                                SubstCalleeTy.getSwiftRValueType(), Subs);
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index 670e9b2..3fbfeba 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -344,7 +344,9 @@
   }
 }
 
-static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture,
+static void emitCaptureArguments(SILGenFunction &gen,
+                                 AnyFunctionRef closure,
+                                 CapturedValue capture,
                                  unsigned ArgNo) {
 
   auto *VD = capture.getDecl();
@@ -357,7 +359,12 @@
     auto interfaceType = cast<VarDecl>(VD)->getInterfaceType();
     if (!interfaceType->hasTypeParameter()) return interfaceType;
 
-    auto genericEnv = gen.F.getGenericEnvironment();
+    // NB: The generic signature may be elided from the lowered function type
+    // if the function is in a fully-specialized context, but we still need to
+    // canonicalize references to the generic parameters that may appear in
+    // non-canonical types in that context. We need the original generic
+    // environment from the AST for that.
+    auto genericEnv = closure.getGenericEnvironment();
     return genericEnv->mapTypeIntoContext(gen.F.getModule().getSwiftModule(),
                                           interfaceType);
   };
@@ -446,7 +453,7 @@
       return;
     }
 
-    emitCaptureArguments(*this, capture, ++ArgNo);
+    emitCaptureArguments(*this, TheClosure, capture, ++ArgNo);
   }
 }
 
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index 958d9b7..28e59a6 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -3548,7 +3548,7 @@
 
   // Always look at the parameters in the last parameter list.
   for (auto param : *afd->getParameterLists().back()) {
-    paramTypes.push_back(getTypeNameForOmission(param->getType())
+    paramTypes.push_back(getTypeNameForOmission(param->getInterfaceType())
                          .withDefaultArgument(param->isDefaultArgument()));
   }
   
@@ -3616,10 +3616,10 @@
 Optional<Identifier> TypeChecker::omitNeedlessWords(VarDecl *var) {
   auto &Context = var->getASTContext();
 
-  if (!var->hasType())
+  if (!var->hasInterfaceType())
     validateDecl(var);
 
-  if (var->isInvalid() || !var->hasType())
+  if (var->isInvalid() || !var->hasInterfaceType())
     return None;
 
   if (var->getName().empty())
@@ -3650,7 +3650,7 @@
 
   // Omit needless words.
   StringScratchSpace scratch;
-  OmissionTypeName typeName = getTypeNameForOmission(var->getType());
+  OmissionTypeName typeName = getTypeNameForOmission(var->getInterfaceType());
   OmissionTypeName contextTypeName = getTypeNameForOmission(contextType);
   if (::omitNeedlessWords(name, { }, "", typeName, contextTypeName, { },
                           /*returnsSelf=*/false, true, allPropertyNames,
diff --git a/test/SILGen/capture-canonicalization.swift b/test/SILGen/capture-canonicalization.swift
new file mode 100644
index 0000000..6ecdf3d
--- /dev/null
+++ b/test/SILGen/capture-canonicalization.swift
@@ -0,0 +1,14 @@
+// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+
+struct Foo<T> {}
+struct Bar {}
+
+extension Foo where T == Bar {
+  func foo(x: T) -> Bar {
+    // CHECK-LABEL: sil shared @{{.*}}3foo{{.*}}4foo2{{.*}} : $@convention(thin) (Bar) -> Bar
+    func foo2() -> Bar {
+      return x
+    }
+    return foo2()
+  }
+}
diff --git a/test/SourceKit/Misc/ignore_bridging_pch.swift b/test/SourceKit/Misc/ignore_bridging_pch.swift
new file mode 100644
index 0000000..b2c9812
--- /dev/null
+++ b/test/SourceKit/Misc/ignore_bridging_pch.swift
@@ -0,0 +1,7 @@
+// RUN: %sourcekitd-test -req=complete -pos=5:3 %s -- -enable-bridging-pch %s | %FileCheck %s
+// RUN: %sourcekitd-test -req=complete -pos=5:3 %s -- -disable-bridging-pch %s | %FileCheck %s
+
+var s = 10
+s.
+
+// CHECK: littleEndian
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
index 787030e..2ff19fa 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
@@ -370,6 +370,9 @@
       continue;
     if (Arg == "-embed-bitcode")
       continue;
+    if (Arg == "-enable-bridging-pch" ||
+        Arg == "-disable-bridging-pch")
+      continue;
     NewArgs.push_back(CArg);
   }
 }
diff --git a/validation-test/Sema/protocol_typo_correction.swift b/validation-test/Sema/protocol_typo_correction.swift
new file mode 100644
index 0000000..14feac4
--- /dev/null
+++ b/validation-test/Sema/protocol_typo_correction.swift
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %target-swift-frontend -emit-module -D LIB %s -o %t/Lib.swiftmodule
+// RUN: %target-swift-frontend -I %t -typecheck %s -verify
+// REQUIRES: objc_interop
+
+#if LIB
+
+import Foundation
+
+@objc public protocol Proto {
+  @objc optional func method(_: Int, for object: NSObject, dividing double: Double)
+}
+
+#else
+
+import Foundation
+import Lib
+
+class Impl: Proto {
+  func methodWithInt(_: Int, forObject object: NSObject, dividingDouble: Double) { }
+  // expected-warning@-1 {{instance method 'methodWithInt(_:forObject:dividingDouble:)' nearly matches optional requirement 'method(_:for:dividing:)' of protocol 'Proto'}}
+  // expected-note@-2{{rename to 'method(_:for:dividing:)' to satisfy this requirement}}{{8-21=method}}{{30-39=for}}{{58-58=dividing }}{{none}}
+  // expected-note@-3{{move 'methodWithInt(_:forObject:dividingDouble:)' to an extension to silence this warning}}
+  // expected-note@-4{{make 'methodWithInt(_:forObject:dividingDouble:)' private to silence this warning}}{{3-3=private }}
+}
+
+#endif