Skip to content

Commit 2488a97

Browse files
committed
[Sema] Update diagnostics.
1 parent c5974ed commit 2488a97

File tree

6 files changed

+50
-31
lines changed

6 files changed

+50
-31
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,8 @@ ERROR(expr_keypath_mutating_getter,none,
664664
"which has a mutating getter",
665665
(const ValueDecl *, bool))
666666
ERROR(expr_keypath_static_member,none,
667-
"%select{key path|dynamic key path member lookup}1 cannot refer to static member %0",
668-
(const ValueDecl *, bool))
667+
"static member %0 cannot be used on instance of type %1",
668+
(const ValueDecl *, Type))
669669
ERROR(expr_keypath_enum_case,none,
670670
"%select{key path|dynamic key path member lookup}1 cannot refer to enum case %0",
671671
(const ValueDecl *, bool))

include/swift/Sema/CSFix.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,11 +2037,12 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
20372037
} Kind;
20382038

20392039
ValueDecl *Member;
2040+
Type BaseType;
20402041

2041-
AllowInvalidRefInKeyPath(ConstraintSystem &cs, RefKind kind,
2042+
AllowInvalidRefInKeyPath(ConstraintSystem &cs, Type baseType, RefKind kind,
20422043
ValueDecl *member, ConstraintLocator *locator)
20432044
: ConstraintFix(cs, FixKind::AllowInvalidRefInKeyPath, locator),
2044-
Kind(kind), Member(member) {}
2045+
Kind(kind), Member(member), BaseType(baseType) {}
20452046

20462047
public:
20472048
std::string getName() const override {
@@ -2064,8 +2065,9 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
20642065
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
20652066

20662067
/// Determine whether give reference requires a fix and produce one.
2067-
static AllowInvalidRefInKeyPath *
2068-
forRef(ConstraintSystem &cs, ValueDecl *member, ConstraintLocator *locator);
2068+
static AllowInvalidRefInKeyPath *forRef(ConstraintSystem &cs, Type baseType,
2069+
ValueDecl *member,
2070+
ConstraintLocator *locator);
20692071

20702072
bool isEqual(const ConstraintFix *other) const;
20712073

@@ -2074,8 +2076,8 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
20742076
}
20752077

20762078
private:
2077-
static AllowInvalidRefInKeyPath *create(ConstraintSystem &cs, RefKind kind,
2078-
ValueDecl *member,
2079+
static AllowInvalidRefInKeyPath *create(ConstraintSystem &cs, Type baseType,
2080+
RefKind kind, ValueDecl *member,
20792081
ConstraintLocator *locator);
20802082
};
20812083

lib/Sema/CSDiagnostics.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4973,10 +4973,10 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
49734973
}
49744974

49754975
// If this is a reference to a static member by one of the key path
4976-
// components, let's provide a tailored diagnostic and return because
4977-
// that is unsupported so there is no fix-it.
4976+
// components, let's provide a tailored diagnostic with fix-it.
49784977
if (locator->isInKeyPathComponent()) {
4979-
InvalidStaticMemberRefInKeyPath failure(getSolution(), Member, locator);
4978+
InvalidStaticMemberRefInKeyPath failure(getSolution(), BaseType, Member,
4979+
locator);
49804980
return failure.diagnoseAsError();
49814981
}
49824982

@@ -6268,8 +6268,18 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
62686268
}
62696269

62706270
bool InvalidStaticMemberRefInKeyPath::diagnoseAsError() {
6271-
emitDiagnostic(diag::expr_keypath_static_member, getMember(),
6272-
isForKeyPathDynamicMemberLookup());
6271+
auto *KPE = getAsExpr<KeyPathExpr>(getRawAnchor());
6272+
auto rootTyRepr = KPE->getExplicitRootType();
6273+
auto isProtocol = getBaseType()->isExistentialType();
6274+
6275+
if (rootTyRepr && !isProtocol) {
6276+
emitDiagnostic(diag::expr_keypath_static_member, getMember(), getBaseType())
6277+
.fixItInsert(rootTyRepr->getEndLoc(), ".Type");
6278+
} else {
6279+
emitDiagnostic(diag::expr_keypath_static_member, getMember(),
6280+
getBaseType());
6281+
}
6282+
62736283
return true;
62746284
}
62756285

lib/Sema/CSDiagnostics.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,20 +1751,25 @@ class InvalidMemberRefInKeyPath : public FailureDiagnostic {
17511751
};
17521752

17531753
/// Diagnose an attempt to reference a static member as a key path component
1754-
/// e.g.
1754+
/// without .Type e.g.
17551755
///
17561756
/// ```swift
17571757
/// struct S {
17581758
/// static var foo: Int = 42
17591759
/// }
17601760
///
1761-
/// _ = \S.Type.foo
1761+
/// _ = \S.foo
17621762
/// ```
17631763
class InvalidStaticMemberRefInKeyPath final : public InvalidMemberRefInKeyPath {
1764+
Type BaseType;
1765+
17641766
public:
1765-
InvalidStaticMemberRefInKeyPath(const Solution &solution, ValueDecl *member,
1766-
ConstraintLocator *locator)
1767-
: InvalidMemberRefInKeyPath(solution, member, locator) {}
1767+
InvalidStaticMemberRefInKeyPath(const Solution &solution, Type baseType,
1768+
ValueDecl *member, ConstraintLocator *locator)
1769+
: InvalidMemberRefInKeyPath(solution, member, locator),
1770+
BaseType(baseType->getRValueType()) {}
1771+
1772+
Type getBaseType() const { return BaseType; }
17681773

17691774
bool diagnoseAsError() override;
17701775
};

lib/Sema/CSFix.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,42 +1250,43 @@ bool AllowInvalidRefInKeyPath::isEqual(const ConstraintFix *other) const {
12501250
}
12511251

12521252
AllowInvalidRefInKeyPath *
1253-
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, ValueDecl *member,
1253+
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, Type baseType,
1254+
ValueDecl *member,
12541255
ConstraintLocator *locator) {
12551256
// Referencing (instance or static) methods in key path is
12561257
// not currently allowed.
12571258
if (isa<FuncDecl>(member))
1258-
return AllowInvalidRefInKeyPath::create(cs, RefKind::Method, member,
1259-
locator);
1259+
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::Method,
1260+
member, locator);
12601261

12611262
// Referencing enum cases in key path is not currently allowed.
12621263
if (isa<EnumElementDecl>(member)) {
1263-
return AllowInvalidRefInKeyPath::create(cs, RefKind::EnumCase, member,
1264-
locator);
1264+
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::EnumCase,
1265+
member, locator);
12651266
}
12661267

12671268
// Referencing initializers in key path is not currently allowed.
12681269
if (isa<ConstructorDecl>(member))
1269-
return AllowInvalidRefInKeyPath::create(cs, RefKind::Initializer,
1270+
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::Initializer,
12701271
member, locator);
12711272

12721273
if (auto *storage = dyn_cast<AbstractStorageDecl>(member)) {
12731274
// Referencing members with mutating getters in key path is not
12741275
// currently allowed.
12751276
if (storage->isGetterMutating())
1276-
return AllowInvalidRefInKeyPath::create(cs, RefKind::MutatingGetter,
1277-
member, locator);
1277+
return AllowInvalidRefInKeyPath::create(
1278+
cs, baseType, RefKind::MutatingGetter, member, locator);
12781279
}
12791280

12801281
return nullptr;
12811282
}
12821283

12831284
AllowInvalidRefInKeyPath *
1284-
AllowInvalidRefInKeyPath::create(ConstraintSystem &cs, RefKind kind,
1285-
ValueDecl *member,
1285+
AllowInvalidRefInKeyPath::create(ConstraintSystem &cs, Type baseType,
1286+
RefKind kind, ValueDecl *member,
12861287
ConstraintLocator *locator) {
12871288
return new (cs.getAllocator())
1288-
AllowInvalidRefInKeyPath(cs, kind, member, locator);
1289+
AllowInvalidRefInKeyPath(cs, baseType, kind, member, locator);
12891290
}
12901291

12911292
bool RemoveAddressOf::diagnose(const Solution &solution, bool asNote) const {

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10611,7 +10611,7 @@ static ConstraintFix *validateInitializerRef(ConstraintSystem &cs,
1061110611
baseType = MetatypeType::get(baseType);
1061210612
} else if (auto *keyPathExpr = getAsExpr<KeyPathExpr>(anchor)) {
1061310613
// Key path can't refer to initializers e.g. `\Type.init`
10614-
return AllowInvalidRefInKeyPath::forRef(cs, init, locator);
10614+
return AllowInvalidRefInKeyPath::forRef(cs, baseType, init, locator);
1061510615
}
1061610616

1061710617
if (!baseType)
@@ -10682,7 +10682,8 @@ static ConstraintFix *fixMemberRef(
1068210682
if (locator->isForKeyPathDynamicMemberLookup() ||
1068310683
locator->isForKeyPathComponent() ||
1068410684
locator->isKeyPathSubscriptComponent()) {
10685-
if (auto *fix = AllowInvalidRefInKeyPath::forRef(cs, decl, locator))
10685+
if (auto *fix =
10686+
AllowInvalidRefInKeyPath::forRef(cs, baseTy, decl, locator))
1068610687
return fix;
1068710688
}
1068810689
}

0 commit comments

Comments
 (0)