Merge pull request #30578 from AnthonyLatsis/memb-fail-qoi

[DiagQoI] Improve fallback fixits for static member on instance errors
This commit is contained in:
Anthony Latsis
2020-03-23 19:31:10 +03:00
committed by GitHub
4 changed files with 29 additions and 12 deletions

View File

@@ -3710,15 +3710,19 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
} }
// Fall back to a fix-it with a full type qualifier // Fall back to a fix-it with a full type qualifier
if (auto *NTD = Member->getDeclContext()->getSelfNominalTypeDecl()) { const Expr *baseExpr = nullptr;
auto type = NTD->getSelfInterfaceType(); if (const auto SE = dyn_cast<SubscriptExpr>(getRawAnchor()))
if (auto *SE = dyn_cast<SubscriptExpr>(getRawAnchor())) { baseExpr = SE->getBase();
auto *baseExpr = SE->getBase(); else if (const auto UDE = dyn_cast<UnresolvedDotExpr>(getRawAnchor()))
Diag->fixItReplace(baseExpr->getSourceRange(), diag::replace_with_type, baseExpr = UDE->getBase();
type);
} else { // An implicit 'self' reference base expression means we should
Diag->fixItInsert(loc, diag::insert_type_qualification, type); // 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; return true;

View File

@@ -344,6 +344,19 @@ class ThisDerived1 : ThisBase1 {
} }
} }
protocol Crawlable {}
extension Crawlable {
static func crawl() {}
}
struct GenericChameleon<U>: Crawlable {
static func chameleon() {}
func testStaticOnInstance(arg: GenericChameleon<Never>) {
arg.chameleon() // expected-error {{static member 'chameleon' cannot be used on instance of type 'GenericChameleon<Never>'}} {{5-8=GenericChameleon<Never>}}
arg.crawl() // expected-error {{static member 'crawl' cannot be used on instance of type 'GenericChameleon<Never>'}} {{5-8=GenericChameleon<Never>}}
}
}
extension ThisBase1 { extension ThisBase1 {
var baseExtProp : Int { var baseExtProp : Int {
get { get {

View File

@@ -473,7 +473,7 @@ enum SE0036 {
func staticReferenceInInstanceMethod() { func staticReferenceInInstanceMethod() {
_ = A // expected-error {{enum case 'A' cannot be used as an instance member}} {{9-9=SE0036.}} _ = 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 _ = SE0036.A
} }

View File

@@ -69,7 +69,7 @@ func test_static_method_value_coerce(_ a: A) {
func test_mixed_overload(_ a: A, x: X, y: Y) { func test_mixed_overload(_ a: A, x: X, y: Y) {
var x1 = a.mixed(x: x) var x1 = a.mixed(x: x)
x1 = 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'}} A.mixed(x) // expected-error{{cannot convert value of type 'X' to expected argument type 'A'}}
var x2 = A.mixed(a)(x: x) 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) { func test_mixed_method_value_coerce(_ a: A) {
var _ : (X) -> X = a.mixed var _ : (X) -> X = a.mixed
var _ : (Y) -> Y = 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 var _ : (A) -> (X) -> X = A.mixed
} }