Merge pull request #17280 from xedin/rdar-41141944-4.2

[4.2][TypeChecker] When formatting witness type for diagnostics don't assu…
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 949d0ac..889a997 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -937,13 +937,13 @@
     if (!other->isAccessibleFrom(currentDC))
       continue;
 
-    const auto markInvalid = [&current, &tc]() {
+    const auto markInvalid = [&current]() {
       current->setInvalid();
       if (auto *varDecl = dyn_cast<VarDecl>(current))
         if (varDecl->hasType())
-          varDecl->setType(ErrorType::get(tc.Context));
+          varDecl->setType(ErrorType::get(varDecl->getType()));
       if (current->hasInterfaceType())
-        current->setInterfaceType(ErrorType::get(tc.Context));
+        current->setInterfaceType(ErrorType::get(current->getInterfaceType()));
     };
 
     // Thwart attempts to override the same declaration more than once.
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 8c68867..8ffde43 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1666,6 +1666,17 @@
     }
   }
 
+  // Redeclaration checking might mark a candidate as `invalid` and
+  // reset it's type to ErrorType, let's dig out original type to
+  // make the diagnostic better.
+  if (auto errorType = type->getAs<ErrorType>()) {
+    auto originalType = errorType->getOriginalType();
+    if (!originalType || !originalType->is<AnyFunctionType>())
+      return type;
+
+    type = originalType;
+  }
+
   return type->castTo<AnyFunctionType>()->getResult();
 }
 
diff --git a/validation-test/compiler_crashers_2_fixed/0160-rdar41141944.swift b/validation-test/compiler_crashers_2_fixed/0160-rdar41141944.swift
new file mode 100644
index 0000000..2c5618c
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0160-rdar41141944.swift
@@ -0,0 +1,18 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify
+// REQUIRES: objc_interop
+
+import Foundation
+
+@objc protocol P {
+  func foo(a arg: Int) // expected-note {{protocol requires function 'foo(a:)' with type '(Int) -> ()'; do you want to add a stub?}}
+}
+
+class C : P {
+// expected-error@-1 {{type 'C' does not conform to protocol 'P'}}
+  var foo: Float = 0.75
+  // expected-note@-1 {{'foo' previously declared here}}
+  // expected-note@-2 {{candidate is not a function}}
+  func foo() {}
+  // expected-error@-1 {{invalid redeclaration of 'foo()'}}
+  // expected-note@-2 {{candidate has non-matching type '() -> ()'}}
+}