From 4bd5a1e4e1d0288b5a13746bc68a8855c6c9af86 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Tue, 11 Jun 2019 11:46:54 -0700 Subject: [PATCH] [Diagnostics] Clarify requirement failure source when it's anchored at assignment While trying to fetch owner type for generic requirement failures anchored at assignment expression, use assignment source as an anchor because that's where requirements come from - conversion from source type to destination. Resolves: rdar://problem/51587755 --- lib/Sema/CSDiagnostics.cpp | 14 +++++++++++--- test/Constraints/sr10906.swift | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 test/Constraints/sr10906.swift diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index a9b4e76c102ec..8ce2e332ea5db 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -111,9 +111,17 @@ Optional FailureDiagnostic::getChoiceFor(Expr *expr) const { } Type RequirementFailure::getOwnerType() const { - return getType(getRawAnchor()) - ->getInOutObjectType() - ->getMetatypeInstanceType(); + auto *anchor = getRawAnchor(); + + // If diagnostic is anchored at assignment expression + // it means that requirement failure happend while trying + // to convert source to destination, which means that + // owner type is actually not an assignment expression + // itself but its source. + if (auto *assignment = dyn_cast(anchor)) + anchor = assignment->getSrc(); + + return getType(anchor)->getInOutObjectType()->getMetatypeInstanceType(); } const GenericContext *RequirementFailure::getGenericContext() const { diff --git a/test/Constraints/sr10906.swift b/test/Constraints/sr10906.swift new file mode 100644 index 0000000000000..1903ca3ca4500 --- /dev/null +++ b/test/Constraints/sr10906.swift @@ -0,0 +1,24 @@ +// RUN: %target-typecheck-verify-swift + +protocol ViewDataSource: class { + func foo() -> [T] +} + +class View { + weak var delegate: ViewDataSource? +} + +final class ViewController { + let view = View() + init() { + view.delegate = self + // expected-error@-1 {{generic class 'ViewController' requires the types 'T' and 'String' be equivalent}} + } +} + +extension ViewController: ViewDataSource where T == String { +// expected-note@-1 {{requirement from conditional conformance of 'ViewController' to 'ViewDataSource'}} + func foo() -> [T] { + return [] + } +}