From efd2069f0c43fed7cde40478f5ef2de266f0de5e Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Wed, 17 Oct 2018 17:35:22 -0700 Subject: [PATCH] [CSDiag] Don't increase candidate curry level if base is ignored When `CandidateCalleeInfo` tries to create a candidate for expression in form of `.` it shouldn't assume that function type of '' would always be at curry level 1, because base could be ignored when it is a module or 'b' refers to a static function. Resolves: rdar://problem/45242032 --- lib/Sema/CalleeCandidateInfo.cpp | 11 ++++++++++- test/Constraints/rdar45242032.swift | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/Constraints/rdar45242032.swift diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp index 16dee0066d1df..26f9ed88e5794 100644 --- a/lib/Sema/CalleeCandidateInfo.cpp +++ b/lib/Sema/CalleeCandidateInfo.cpp @@ -717,7 +717,16 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn, if (auto UDE = dyn_cast(fn)) { declName = UDE->getName().getBaseName().userFacingName(); uncurryLevel = 1; - + + // If base is a module or metatype, this is just a simple + // reference so its curry level should be 0. + if (auto *DRE = dyn_cast(UDE->getBase())) { + if (auto baseType = DRE->getType()) + uncurryLevel = + (baseType->is() || baseType->is()) ? 0 + : 1; + } + // If we actually resolved the member to use, return it. auto loc = CS.getConstraintLocator(UDE, ConstraintLocator::Member); if (auto *member = CS.findResolvedMemberRef(loc)) { diff --git a/test/Constraints/rdar45242032.swift b/test/Constraints/rdar45242032.swift new file mode 100644 index 0000000000000..3e24e88c96dea --- /dev/null +++ b/test/Constraints/rdar45242032.swift @@ -0,0 +1,22 @@ +// RUN: %target-typecheck-verify-swift -module-name M + +protocol P { + var v: String { get } +} + +func foo(bar: [P], baz: [P]) { +// expected-note@-1 {{'foo(bar:baz:)' declared here}} +} + +struct S { + static func bar(fiz: [P], baz: [P]) {} +// expected-note@-1 {{'bar(fiz:baz:)' declared here}} +} + +do { + let _ = M.foo(bar & // expected-error {{missing argument for parameter 'bar' in call}} +} // expected-error {{expected expression after operator}} + +do { + let _ = S.bar(fiz & // expected-error {{missing argument for parameter 'fiz' in call}} +} // expected-error {{expected expression after operator}}