Skip to content

Commit 02b9bcb

Browse files
committed
[Sema] Update diagnostics.
1 parent 1c494c4 commit 02b9bcb

File tree

6 files changed

+49
-32
lines changed

6 files changed

+49
-32
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,6 @@ ERROR(expr_keypath_mutating_getter,none,
663663
"%select{key path|dynamic key path member lookup}1 cannot refer to %0, "
664664
"which has a mutating getter",
665665
(const ValueDecl *, bool))
666-
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))
669666
ERROR(expr_keypath_enum_case,none,
670667
"%select{key path|dynamic key path member lookup}1 cannot refer to enum case %0",
671668
(const ValueDecl *, bool))

include/swift/Sema/CSFix.h

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

20422042
ValueDecl *Member;
2043+
Type BaseType;
20432044

2044-
AllowInvalidRefInKeyPath(ConstraintSystem &cs, RefKind kind,
2045+
AllowInvalidRefInKeyPath(ConstraintSystem &cs, Type baseType, RefKind kind,
20452046
ValueDecl *member, ConstraintLocator *locator)
20462047
: ConstraintFix(cs, FixKind::AllowInvalidRefInKeyPath, locator),
2047-
Kind(kind), Member(member) {}
2048+
Kind(kind), Member(member), BaseType(baseType) {}
20482049

20492050
public:
20502051
std::string getName() const override {
@@ -2067,8 +2068,9 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
20672068
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
20682069

20692070
/// Determine whether give reference requires a fix and produce one.
2070-
static AllowInvalidRefInKeyPath *
2071-
forRef(ConstraintSystem &cs, ValueDecl *member, ConstraintLocator *locator);
2071+
static AllowInvalidRefInKeyPath *forRef(ConstraintSystem &cs, Type baseType,
2072+
ValueDecl *member,
2073+
ConstraintLocator *locator);
20722074

20732075
bool isEqual(const ConstraintFix *other) const;
20742076

@@ -2077,8 +2079,8 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
20772079
}
20782080

20792081
private:
2080-
static AllowInvalidRefInKeyPath *create(ConstraintSystem &cs, RefKind kind,
2081-
ValueDecl *member,
2082+
static AllowInvalidRefInKeyPath *create(ConstraintSystem &cs, Type baseType,
2083+
RefKind kind, ValueDecl *member,
20822084
ConstraintLocator *locator);
20832085
};
20842086

lib/Sema/CSDiagnostics.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4993,10 +4993,10 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
49934993
}
49944994

49954995
// If this is a reference to a static member by one of the key path
4996-
// components, let's provide a tailored diagnostic and return because
4997-
// that is unsupported so there is no fix-it.
4996+
// components, let's provide a tailored diagnostic with fix-it.
49984997
if (locator->isInKeyPathComponent()) {
4999-
InvalidStaticMemberRefInKeyPath failure(getSolution(), Member, locator);
4998+
InvalidStaticMemberRefInKeyPath failure(getSolution(), BaseType, Member,
4999+
locator);
50005000
return failure.diagnoseAsError();
50015001
}
50025002

@@ -6335,8 +6335,19 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
63356335
}
63366336

63376337
bool InvalidStaticMemberRefInKeyPath::diagnoseAsError() {
6338-
emitDiagnostic(diag::expr_keypath_static_member, getMember(),
6339-
isForKeyPathDynamicMemberLookup());
6338+
auto *KPE = getAsExpr<KeyPathExpr>(getRawAnchor());
6339+
auto rootTyRepr = KPE->getExplicitRootType();
6340+
auto isProtocol = getBaseType()->isExistentialType();
6341+
6342+
if (rootTyRepr && !isProtocol) {
6343+
emitDiagnostic(diag::could_not_use_type_member_on_instance, getBaseType(),
6344+
DeclNameRef(getMember()->getName()))
6345+
.fixItInsert(rootTyRepr->getEndLoc(), ".Type");
6346+
} else {
6347+
emitDiagnostic(diag::could_not_use_type_member_on_instance, getBaseType(),
6348+
DeclNameRef(getMember()->getName()));
6349+
}
6350+
63406351
return true;
63416352
}
63426353

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
@@ -1274,42 +1274,43 @@ bool AllowInvalidRefInKeyPath::isEqual(const ConstraintFix *other) const {
12741274
}
12751275

12761276
AllowInvalidRefInKeyPath *
1277-
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, ValueDecl *member,
1277+
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, Type baseType,
1278+
ValueDecl *member,
12781279
ConstraintLocator *locator) {
12791280
// Referencing (instance or static) methods in key path is
12801281
// not currently allowed.
12811282
if (isa<FuncDecl>(member))
1282-
return AllowInvalidRefInKeyPath::create(cs, RefKind::Method, member,
1283-
locator);
1283+
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::Method,
1284+
member, locator);
12841285

12851286
// Referencing enum cases in key path is not currently allowed.
12861287
if (isa<EnumElementDecl>(member)) {
1287-
return AllowInvalidRefInKeyPath::create(cs, RefKind::EnumCase, member,
1288-
locator);
1288+
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::EnumCase,
1289+
member, locator);
12891290
}
12901291

12911292
// Referencing initializers in key path is not currently allowed.
12921293
if (isa<ConstructorDecl>(member))
1293-
return AllowInvalidRefInKeyPath::create(cs, RefKind::Initializer,
1294+
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::Initializer,
12941295
member, locator);
12951296

12961297
if (auto *storage = dyn_cast<AbstractStorageDecl>(member)) {
12971298
// Referencing members with mutating getters in key path is not
12981299
// currently allowed.
12991300
if (storage->isGetterMutating())
1300-
return AllowInvalidRefInKeyPath::create(cs, RefKind::MutatingGetter,
1301-
member, locator);
1301+
return AllowInvalidRefInKeyPath::create(
1302+
cs, baseType, RefKind::MutatingGetter, member, locator);
13021303
}
13031304

13041305
return nullptr;
13051306
}
13061307

13071308
AllowInvalidRefInKeyPath *
1308-
AllowInvalidRefInKeyPath::create(ConstraintSystem &cs, RefKind kind,
1309-
ValueDecl *member,
1309+
AllowInvalidRefInKeyPath::create(ConstraintSystem &cs, Type baseType,
1310+
RefKind kind, ValueDecl *member,
13101311
ConstraintLocator *locator) {
13111312
return new (cs.getAllocator())
1312-
AllowInvalidRefInKeyPath(cs, kind, member, locator);
1313+
AllowInvalidRefInKeyPath(cs, baseType, kind, member, locator);
13131314
}
13141315

13151316
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
@@ -10443,7 +10443,7 @@ static ConstraintFix *validateInitializerRef(ConstraintSystem &cs,
1044310443
baseType = MetatypeType::get(baseType);
1044410444
} else if (auto *keyPathExpr = getAsExpr<KeyPathExpr>(anchor)) {
1044510445
// Key path can't refer to initializers e.g. `\Type.init`
10446-
return AllowInvalidRefInKeyPath::forRef(cs, init, locator);
10446+
return AllowInvalidRefInKeyPath::forRef(cs, baseType, init, locator);
1044710447
}
1044810448

1044910449
if (!baseType)
@@ -10514,7 +10514,8 @@ static ConstraintFix *fixMemberRef(
1051410514
if (locator->isForKeyPathDynamicMemberLookup() ||
1051510515
locator->isForKeyPathComponent() ||
1051610516
locator->isKeyPathSubscriptComponent()) {
10517-
if (auto *fix = AllowInvalidRefInKeyPath::forRef(cs, decl, locator))
10517+
if (auto *fix =
10518+
AllowInvalidRefInKeyPath::forRef(cs, baseTy, decl, locator))
1051810519
return fix;
1051910520
}
1052010521
}

0 commit comments

Comments
 (0)