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 = [¤t, &tc]() {
+ const auto markInvalid = [¤t]() {
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 '() -> ()'}}
+}