Skip to content

Commit d721b6e

Browse files
authored
Merge pull request #77302 from xedin/se-0438-enhancements
[Frontend/ConstraintSystem] NFC: SE-0438 implementation enhancements
2 parents f288e39 + 5d77f3c commit d721b6e

File tree

13 files changed

+85
-33
lines changed

13 files changed

+85
-33
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,13 @@ ERROR(expr_keypath_mutating_getter,none,
666666
ERROR(expr_keypath_static_member,none,
667667
"%select{key path|dynamic key path member lookup}1 cannot refer to static member %0",
668668
(const ValueDecl *, bool))
669+
ERROR(keypath_static_member_access_from_unsupported_module,none,
670+
"%select{key path|dynamic key path member lookup}3 cannot refer "
671+
"to static member %1 of type %0 from module %2",
672+
(Type, const ValueDecl *, const ModuleDecl *, bool))
673+
NOTE(keypath_static_member_access_from_unsupported_module_note,none,
674+
"rebuild %0 to enable static member use in key paths",
675+
(const ModuleDecl *))
669676
ERROR(expr_keypath_enum_case,none,
670677
"%select{key path|dynamic key path member lookup}1 cannot refer to enum case %0",
671678
(const ValueDecl *, bool))

include/swift/Basic/Features.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,6 @@ EXPERIMENTAL_FEATURE(MacrosOnImports, true)
235235
EXPERIMENTAL_FEATURE(TupleConformances, false)
236236
EXPERIMENTAL_FEATURE(FullTypedThrows, false)
237237
EXPERIMENTAL_FEATURE(SameElementRequirements, false)
238-
EXPERIMENTAL_FEATURE(KeyPathWithStaticMembers, false)
239238

240239
// Whether to enable @_used and @_section attributes
241240
EXPERIMENTAL_FEATURE(SymbolLinkageMarkers, true)

include/swift/Sema/CSFix.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,9 +2026,11 @@ class TreatKeyPathSubscriptIndexAsHashable final : public ConstraintFix {
20262026

20272027
class AllowInvalidRefInKeyPath final : public ConstraintFix {
20282028
enum RefKind {
2029+
// Allow invalid references to static members i.e. on instance of a type.
2030+
StaticMember,
20292031
// Allow a reference to a static member as a key path component if it is
20302032
// declared in a module with built with Swift 6.0 compiler version or older.
2031-
StaticMember,
2033+
UnsupportedStaticMember,
20322034
// Allow a reference to a declaration with mutating getter as
20332035
// a key path component.
20342036
MutatingGetter,
@@ -2054,7 +2056,10 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
20542056
std::string getName() const override {
20552057
switch (Kind) {
20562058
case RefKind::StaticMember:
2057-
return "allow reference to a static member as a key path component";
2059+
return "allow reference to a static member on invalid base in key path "
2060+
"context";
2061+
case RefKind::UnsupportedStaticMember:
2062+
return "allow unsupported static member reference";
20582063
case RefKind::MutatingGetter:
20592064
return "allow reference to a member with mutating getter as a key "
20602065
"path component";

lib/AST/FeatureSet.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ UNINTERESTING_FEATURE(GroupActorErrors)
198198
UNINTERESTING_FEATURE(SameElementRequirements)
199199
UNINTERESTING_FEATURE(UnspecifiedMeansMainActorIsolated)
200200
UNINTERESTING_FEATURE(GlobalActorInferenceCutoff)
201-
UNINTERESTING_FEATURE(KeyPathWithStaticMembers)
202201
UNINTERESTING_FEATURE(GenerateForceToMainActorThunks)
203202

204203
static bool usesFeatureSendingArgsAndResults(Decl *decl) {

lib/Sema/CSDiagnostics.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6337,28 +6337,33 @@ SourceLoc InvalidMemberRefInKeyPath::getLoc() const {
63376337
}
63386338

63396339
bool InvalidStaticMemberRefInKeyPath::diagnoseAsError() {
6340-
auto *KPE = getAsExpr<KeyPathExpr>(getRawAnchor());
6341-
auto rootTyRepr = KPE->getExplicitRootType();
6342-
auto isProtocol = getBaseType()->isExistentialType();
6343-
6344-
if (!getConstraintSystem().getASTContext().LangOpts.hasFeature(
6345-
Feature::KeyPathWithStaticMembers)) {
6346-
emitDiagnostic(diag::expr_keypath_static_member, getMember(),
6347-
isForKeyPathDynamicMemberLookup());
6348-
} else {
6349-
if (rootTyRepr && !isProtocol) {
6350-
emitDiagnostic(diag::could_not_use_type_member_on_instance, getBaseType(),
6351-
DeclNameRef(getMember()->getName()))
6352-
.fixItInsert(rootTyRepr->getEndLoc(), ".Type");
6353-
} else {
6340+
auto diagnostic =
63546341
emitDiagnostic(diag::could_not_use_type_member_on_instance, getBaseType(),
63556342
DeclNameRef(getMember()->getName()));
6343+
6344+
// Suggest adding `.Type` to an explicit root if possible.
6345+
if (auto *keyPath = getAsExpr<KeyPathExpr>(getRawAnchor())) {
6346+
if (auto *explicitRoot = keyPath->getExplicitRootType()) {
6347+
if (explicitRoot && !getBaseType()->isExistentialType())
6348+
diagnostic.fixItInsert(explicitRoot->getEndLoc(), ".Type");
63566349
}
63576350
}
63586351

63596352
return true;
63606353
}
63616354

6355+
bool UnsupportedStaticMemberRefInKeyPath::diagnoseAsError() {
6356+
auto *member = getMember();
6357+
auto *module = member->getDeclContext()->getParentModule();
6358+
6359+
emitDiagnostic(diag::keypath_static_member_access_from_unsupported_module,
6360+
BaseType->getMetatypeInstanceType(), member, module,
6361+
getLocator()->isForKeyPathDynamicMemberLookup());
6362+
emitDiagnostic(
6363+
diag::keypath_static_member_access_from_unsupported_module_note, module);
6364+
return true;
6365+
}
6366+
63626367
bool InvalidEnumCaseRefInKeyPath::diagnoseAsError() {
63636368
emitDiagnostic(diag::expr_keypath_enum_case, getMember(),
63646369
isForKeyPathDynamicMemberLookup());

lib/Sema/CSDiagnostics.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1767,13 +1767,31 @@ class InvalidStaticMemberRefInKeyPath final : public InvalidMemberRefInKeyPath {
17671767
InvalidStaticMemberRefInKeyPath(const Solution &solution, Type baseType,
17681768
ValueDecl *member, ConstraintLocator *locator)
17691769
: InvalidMemberRefInKeyPath(solution, member, locator),
1770-
BaseType(baseType->getRValueType()) {}
1770+
BaseType(resolveType(baseType)->getRValueType()) {}
17711771

17721772
Type getBaseType() const { return BaseType; }
17731773

17741774
bool diagnoseAsError() override;
17751775
};
17761776

1777+
/// Diagnose an attempt to reference a static member from an unsupported module.
1778+
///
1779+
/// Only modules built either from source with 6.1+ compiler or
1780+
/// from .swiftinterface that was generated by 6.1+ compiler are supported.
1781+
class UnsupportedStaticMemberRefInKeyPath final
1782+
: public InvalidMemberRefInKeyPath {
1783+
Type BaseType;
1784+
1785+
public:
1786+
UnsupportedStaticMemberRefInKeyPath(const Solution &solution, Type baseType,
1787+
ValueDecl *member,
1788+
ConstraintLocator *locator)
1789+
: InvalidMemberRefInKeyPath(solution, member, locator),
1790+
BaseType(resolveType(baseType)->getRValueType()) {}
1791+
1792+
bool diagnoseAsError() override;
1793+
};
1794+
17771795
/// Diagnose an attempt to reference an enum case as a key path component
17781796
/// e.g.
17791797
///

lib/Sema/CSFix.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,15 @@ bool AllowInvalidRefInKeyPath::diagnose(const Solution &solution,
12311231
bool asNote) const {
12321232
switch (Kind) {
12331233
case RefKind::StaticMember: {
1234-
return false;
1234+
InvalidStaticMemberRefInKeyPath failure(solution, BaseType, Member,
1235+
getLocator());
1236+
return failure.diagnose(asNote);
1237+
}
1238+
1239+
case RefKind::UnsupportedStaticMember: {
1240+
UnsupportedStaticMemberRefInKeyPath failure(solution, BaseType, Member,
1241+
getLocator());
1242+
return failure.diagnose(asNote);
12351243
}
12361244

12371245
case RefKind::EnumCase: {
@@ -1281,12 +1289,23 @@ AllowInvalidRefInKeyPath *
12811289
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, Type baseType,
12821290
ValueDecl *member,
12831291
ConstraintLocator *locator) {
1292+
if (member->isStatic() && !isa<FuncDecl>(member)) {
1293+
// References to static members are supported only for modules that
1294+
// are built with 6.1+ compilers, libraries produced by earlier
1295+
// compilers don't have required symbols.
1296+
if (auto *module = member->getDeclContext()->getParentModule()) {
1297+
if (module->isBuiltFromInterface() &&
1298+
module->getSwiftInterfaceCompilerVersion() <
1299+
llvm::VersionTuple(6, 1)) {
1300+
return AllowInvalidRefInKeyPath::create(
1301+
cs, baseType, RefKind::UnsupportedStaticMember, member, locator);
1302+
}
1303+
}
12841304

1285-
if (!cs.getASTContext().LangOpts.hasFeature(
1286-
Feature::KeyPathWithStaticMembers) &&
1287-
member->isStatic())
1288-
return AllowInvalidRefInKeyPath::create(cs, baseType, RefKind::StaticMember,
1289-
member, locator);
1305+
if (!baseType->getRValueType()->is<AnyMetatypeType>())
1306+
return AllowInvalidRefInKeyPath::create(
1307+
cs, baseType, RefKind::StaticMember, member, locator);
1308+
}
12901309

12911310
// Referencing (instance or static) methods in key path is
12921311
// not currently allowed.

test/Interpreter/keypath.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-feature -Xfrontend KeyPathWithStaticMembers) | %FileCheck %s
1+
// RUN: %target-run-simple-swift | %FileCheck %s
22

33
// REQUIRES: asserts
44
// REQUIRES: executable_test

test/Interpreter/static_keypaths.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
// RUN: split-file %s %t/src
33

44
/// Build LibA
5-
// RUN: %host-build-swift %t/src/LibA.swift -swift-version 5 -enable-experimental-feature KeyPathWithStaticMembers -emit-module -emit-library -enable-library-evolution -module-name LibA -o %t/%target-library-name(LibA) -emit-module-interface-path %t/LibA.swiftinterface
5+
// RUN: %host-build-swift %t/src/LibA.swift -swift-version 5 -emit-module -emit-library -enable-library-evolution -module-name LibA -o %t/%target-library-name(LibA) -emit-module-interface-path %t/LibA.swiftinterface
66

77
// Build LibB
8-
// RUN: %target-build-swift %t/src/LibB.swift -I %t -L %t -l LibA -swift-version 5 -enable-experimental-feature KeyPathWithStaticMembers -emit-module -emit-library -module-name LibB -o %t/%target-library-name(LibB)
8+
// RUN: %target-build-swift %t/src/LibB.swift -I %t -L %t -l LibA -swift-version 5 -emit-module -emit-library -module-name LibB -o %t/%target-library-name(LibB)
99

1010
// Build LibC
11-
// RUN: %target-build-swift %t/src/LibC.swift -I %t -L %t -l LibA -swift-version 5 -enable-experimental-feature KeyPathWithStaticMembers -emit-module -emit-library -module-name LibC -o %t/%target-library-name(LibC)
11+
// RUN: %target-build-swift %t/src/LibC.swift -I %t -L %t -l LibA -swift-version 5 -emit-module -emit-library -module-name LibC -o %t/%target-library-name(LibC)
1212

1313
// Build & run main.swift
1414
// RUN: %target-build-swift -I %t -L %t -l LibA -l LibB -l LibC %t/src/main.swift -o %t/a.out

test/SILGen/keypaths.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-emit-silgen -enable-experimental-feature KeyPathWithStaticMembers -target %target-swift-5.1-abi-triple -disable-experimental-parser-round-trip -parse-stdlib -module-name keypaths %s | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen -target %target-swift-5.1-abi-triple -disable-experimental-parser-round-trip -parse-stdlib -module-name keypaths %s | %FileCheck %s
22
// FIXME: Remove '-disable-experimental-parser-round-trip'.
33

44
// REQUIRES: asserts

test/SILOptimizer/access_wmo_diagnose.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -enable-experimental-feature KeyPathWithStaticMembers -parse-as-library -emit-sil -enforce-exclusivity=checked -primary-file %s -o /dev/null -verify
1+
// RUN: %target-swift-frontend -parse-as-library -emit-sil -enforce-exclusivity=checked -primary-file %s -o /dev/null -verify
22

33
// REQUIRES: asserts
44

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -enable-experimental-feature KeyPathWithStaticMembers
1+
// RUN: %target-typecheck-verify-swift
22

33
// REQUIRES: asserts
44

test/expr/unary/keypath/keypath.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -typecheck -enable-experimental-feature KeyPathWithStaticMembers -parse-as-library %s -verify
1+
// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify
22

33
// REQUIRES: asserts
44

0 commit comments

Comments
 (0)