Skip to content

Commit de18967

Browse files
joewillshertkremenek
authored andcommitted
[Sema] Improved error message for static functions on existential metatypes (#2127)
Type level lookups can fail because the lookup is on an existential metatype, like `MyProtocol.staticMethod(_:)` is invalid; however the error message is unclear: “static member 'staticMethod(_:)' cannot be used on instance of type ‘MyProtocol.Protocol’”. This fix checks the base of member lookups that failed with the reason UR_TypeMemberOnInstance for being existential metatypes. It produces the clearer message “static member ‘staticMethod(_:)’ cannot be used on protocol metatype ‘MyProtocol.Protocol’”. This change makes it clear that the use of a static member on the *existential* metatype is the problem.
1 parent abed7b6 commit de18967

File tree

5 files changed

+23
-9
lines changed

5 files changed

+23
-9
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ ERROR(could_not_use_type_member,none,
9393
ERROR(could_not_use_type_member_on_instance,none,
9494
"static member %1 cannot be used on instance of type %0",
9595
(Type, DeclName))
96+
ERROR(could_not_use_type_member_on_existential,none,
97+
"static member %1 cannot be used on protocol metatype %0",
98+
(Type, DeclName))
9699
ERROR(could_not_use_instance_member_on_type,none,
97100
"instance member %1 cannot be used on type %0",
98101
(Type, DeclName))

lib/Sema/CSDiag.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,10 +2251,21 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
22512251
instanceTy, memberName)
22522252
.highlight(baseRange).highlight(nameLoc.getSourceRange());
22532253
return;
2254+
22542255
case MemberLookupResult::UR_TypeMemberOnInstance:
2255-
diagnose(loc, diag::could_not_use_type_member_on_instance,
2256-
baseObjTy, memberName)
2257-
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2256+
if (instanceTy->isExistentialType() && baseObjTy->is<AnyMetatypeType>()) {
2257+
// If the base of the lookup is an existential metatype, emit an
2258+
// error specific to that
2259+
diagnose(loc, diag::could_not_use_type_member_on_existential,
2260+
baseObjTy, memberName)
2261+
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2262+
} else {
2263+
// Otherwise the static member lookup was invalid because it was
2264+
// called on an instance
2265+
diagnose(loc, diag::could_not_use_type_member_on_instance,
2266+
baseObjTy, memberName)
2267+
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2268+
}
22582269
return;
22592270

22602271
case MemberLookupResult::UR_MutatingMemberOnRValue:

lib/Sema/ConstraintSystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,15 +820,15 @@ struct MemberLookupResult {
820820
/// Argument labels don't match.
821821
UR_LabelMismatch,
822822

823-
/// This uses a type like Self it its signature that cannot be used on an
823+
/// This uses a type like Self in its signature that cannot be used on an
824824
/// existential box.
825825
UR_UnavailableInExistential,
826826

827827
/// This is an instance member being accessed through something of metatype
828828
/// type.
829829
UR_InstanceMemberOnType,
830830

831-
/// This is a static/class member being access through an instance.
831+
/// This is a static/class member being accessed through an instance.
832832
UR_TypeMemberOnInstance,
833833

834834
/// This is a mutating member, being used on an rvalue.

test/Constraints/members.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ func staticExistential(_ p: P.Type, pp: P.Protocol) {
294294
_ = p.mut // expected-error{{instance member 'mut' cannot be used on type 'P'}}
295295

296296
// Static member of metatype -- not allowed
297-
_ = pp.tum // expected-error{{static member 'tum' cannot be used on instance of type 'P.Protocol'}}
298-
_ = P.tum // expected-error{{static member 'tum' cannot be used on instance of type 'P.Protocol'}}
297+
_ = pp.tum // expected-error{{static member 'tum' cannot be used on protocol metatype 'P.Protocol'}}
298+
_ = P.tum // expected-error{{static member 'tum' cannot be used on protocol metatype 'P.Protocol'}}
299299

300300
// Static member of extension returning Self)
301301
let _: () -> P = id(p.returnSelfStatic)

test/expr/unary/selector/selector.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ func testSelector(_ c1: C1, p1: P1, obj: AnyObject) {
6363
// Methods on a protocol.
6464
_ = #selector(P1.method4)
6565
_ = #selector(P1.method4(_:b:))
66-
_ = #selector(P1.method5) // FIXME: expected-error{{static member 'method5' cannot be used on instance of type 'P1.Protocol'}}
67-
_ = #selector(P1.method5(_:b:)) // FIXME: expected-error{{static member 'method5(_:b:)' cannot be used on instance of type 'P1.Protocol'}}
66+
_ = #selector(P1.method5) // expected-error{{static member 'method5' cannot be used on protocol metatype 'P1.Protocol'}}
67+
_ = #selector(P1.method5(_:b:)) // expected-error{{static member 'method5(_:b:)' cannot be used on protocol metatype 'P1.Protocol'}}
6868
_ = #selector(p1.method4)
6969
_ = #selector(p1.method4(_:b:))
7070
_ = #selector(p1.dynamicType.method5)

0 commit comments

Comments
 (0)