From 572f0544a22a0526736ef043245268cd7da2d163 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Mon, 23 Mar 2020 08:27:55 +0300 Subject: [PATCH] [DiagQoI] Improve fallback fixits for static member on instance error --- lib/Sema/CSDiagnostics.cpp | 22 +++++++++++++--------- test/NameBinding/name_lookup.swift | 13 +++++++++++++ test/Parse/enum.swift | 2 +- test/TypeCoercion/overload_member.swift | 4 ++-- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 63b80ffeb5e..f8a10fa98a9 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -3708,15 +3708,19 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() { } // Fall back to a fix-it with a full type qualifier - if (auto *NTD = Member->getDeclContext()->getSelfNominalTypeDecl()) { - auto type = NTD->getSelfInterfaceType(); - if (auto *SE = dyn_cast(getRawAnchor())) { - auto *baseExpr = SE->getBase(); - Diag->fixItReplace(baseExpr->getSourceRange(), diag::replace_with_type, - type); - } else { - Diag->fixItInsert(loc, diag::insert_type_qualification, type); - } + const Expr *baseExpr = nullptr; + if (const auto SE = dyn_cast(getRawAnchor())) + baseExpr = SE->getBase(); + else if (const auto UDE = dyn_cast(getRawAnchor())) + baseExpr = UDE->getBase(); + + // An implicit 'self' reference base expression means we should + // prepend with qualification. + if (baseExpr && !baseExpr->isImplicit()) { + Diag->fixItReplace(baseExpr->getSourceRange(), + diag::replace_with_type, baseTy); + } else { + Diag->fixItInsert(loc, diag::insert_type_qualification, baseTy); } return true; diff --git a/test/NameBinding/name_lookup.swift b/test/NameBinding/name_lookup.swift index fb5f62cf994..82881dfbaad 100644 --- a/test/NameBinding/name_lookup.swift +++ b/test/NameBinding/name_lookup.swift @@ -344,6 +344,19 @@ class ThisDerived1 : ThisBase1 { } } +protocol Crawlable {} +extension Crawlable { + static func crawl() {} +} +struct GenericChameleon: Crawlable { + static func chameleon() {} + + func testStaticOnInstance(arg: GenericChameleon) { + arg.chameleon() // expected-error {{static member 'chameleon' cannot be used on instance of type 'GenericChameleon'}} {{5-8=GenericChameleon}} + arg.crawl() // expected-error {{static member 'crawl' cannot be used on instance of type 'GenericChameleon'}} {{5-8=GenericChameleon}} + } +} + extension ThisBase1 { var baseExtProp : Int { get { diff --git a/test/Parse/enum.swift b/test/Parse/enum.swift index 3a51bfaa379..1d982946652 100644 --- a/test/Parse/enum.swift +++ b/test/Parse/enum.swift @@ -473,7 +473,7 @@ enum SE0036 { func staticReferenceInInstanceMethod() { _ = A // expected-error {{enum case 'A' cannot be used as an instance member}} {{9-9=SE0036.}} - _ = self.A // expected-error {{enum case 'A' cannot be used as an instance member}} {{9-9=SE0036.}} + _ = self.A // expected-error {{enum case 'A' cannot be used as an instance member}} {{9-13=SE0036}} _ = SE0036.A } diff --git a/test/TypeCoercion/overload_member.swift b/test/TypeCoercion/overload_member.swift index 4ebd3131fd7..84dc1482c18 100644 --- a/test/TypeCoercion/overload_member.swift +++ b/test/TypeCoercion/overload_member.swift @@ -69,7 +69,7 @@ func test_static_method_value_coerce(_ a: A) { func test_mixed_overload(_ a: A, x: X, y: Y) { var x1 = a.mixed(x: x) x1 = x - var y1 = a.mixed(y: y) // expected-error {{static member 'mixed' cannot be used on instance of type 'A'}} {{12-12=A.}} + var y1 = a.mixed(y: y) // expected-error {{static member 'mixed' cannot be used on instance of type 'A'}} {{12-13=A}} A.mixed(x) // expected-error{{cannot convert value of type 'X' to expected argument type 'A'}} var x2 = A.mixed(a)(x: x) @@ -89,7 +89,7 @@ func test_mixed_overload_coerce(_ a: A, x: inout X, y: Y, z: Z) { func test_mixed_method_value_coerce(_ a: A) { var _ : (X) -> X = a.mixed var _ : (Y) -> Y = A.mixed - var _ : (Y) -> Y = a.mixed; // expected-error {{static member 'mixed' cannot be used on instance of type 'A'}} {{22-22=A.}} + var _ : (Y) -> Y = a.mixed; // expected-error {{static member 'mixed' cannot be used on instance of type 'A'}} {{22-23=A}} var _ : (A) -> (X) -> X = A.mixed }