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 [] + } +}