Skip to content

Commit 8f3adaf

Browse files
authored
Merge pull request #11953 from jckarter/key-path-subscripts-4.0
Key path subscripts
2 parents 70d7745 + aea947d commit 8f3adaf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2471
-414
lines changed

docs/ABI.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,10 @@ types where the metadata itself has unknown layout.)
830830
global ::= global 'Tm' // merged function
831831
global ::= entity // some identifiable thing
832832
global ::= type type generic-signature? 'T' REABSTRACT-THUNK-TYPE // reabstraction thunk helper function
833+
global ::= entity generic-signature? type type* 'TK' // key path getter
834+
global ::= entity generic-signature? type type* 'Tk' // key path setter
835+
global ::= type generic-signature 'TH' // key path equality
836+
global ::= type generic-signature 'Th' // key path hasher
833837

834838
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function
835839
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,13 @@ class ASTContext {
862862
/// Retrieve a generic signature with a single unconstrained type parameter,
863863
/// like `<T>`.
864864
CanGenericSignature getSingleGenericParameterSignature() const;
865-
866-
/// Whether our effective Swift version is in the Swift 3 family
865+
866+
/// Retrieve a generic signature with a single type parameter conforming
867+
/// to the given existential type.
868+
CanGenericSignature getExistentialSignature(CanType existential,
869+
ModuleDecl *mod);
870+
871+
/// Whether our effective Swift version is in the Swift 3 family.
867872
bool isSwiftVersion3() const { return LangOpts.isSwiftVersion3(); }
868873

869874
private:

include/swift/AST/ASTMangler.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,18 @@ class ASTMangler : public Mangler {
114114
Type FromType, Type ToType,
115115
ModuleDecl *Module);
116116

117-
std::string mangleKeyPathGetterThunkHelper(const VarDecl *property,
117+
std::string mangleKeyPathGetterThunkHelper(const AbstractStorageDecl *property,
118118
GenericSignature *signature,
119-
CanType baseType);
120-
std::string mangleKeyPathSetterThunkHelper(const VarDecl *property,
119+
CanType baseType,
120+
ArrayRef<CanType> subs);
121+
std::string mangleKeyPathSetterThunkHelper(const AbstractStorageDecl *property,
121122
GenericSignature *signature,
122-
CanType baseType);
123+
CanType baseType,
124+
ArrayRef<CanType> subs);
125+
std::string mangleKeyPathEqualsHelper(ArrayRef<CanType> indices,
126+
GenericSignature *signature);
127+
std::string mangleKeyPathHashHelper(ArrayRef<CanType> indices,
128+
GenericSignature *signature);
123129

124130
std::string mangleTypeForDebugger(Type decl, const DeclContext *DC,
125131
GenericEnvironment *GE);

include/swift/AST/DiagnosticsParse.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,15 @@ ERROR(sil_keypath_no_components,none,
584584
"keypath must have at least one component", ())
585585
ERROR(sil_keypath_no_root,none,
586586
"keypath must have a root component declared",())
587+
ERROR(sil_keypath_index_not_hashable,none,
588+
"key path index type %0 does not conform to Hashable", (Type))
589+
ERROR(sil_keypath_index_operand_type_conflict,none,
590+
"conflicting types for key path operand %0: %1 vs. %2",
591+
(unsigned, Type, Type))
592+
ERROR(sil_keypath_no_use_of_operand_in_pattern,none,
593+
"operand %0 is not referenced by any component in the pattern",
594+
(unsigned))
595+
587596
// SIL Basic Blocks
588597
ERROR(expected_sil_block_name,none,
589598
"expected basic block name or '}'", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ ERROR(expr_string_interpolation_outside_string,none,
470470
"string interpolation can only appear inside a string literal", ())
471471
ERROR(unsupported_keypath_tuple_element_reference,none,
472472
"key path cannot reference tuple elements", ())
473+
ERROR(expr_keypath_subscript_index_not_hashable, none,
474+
"subscript index of type %0 in a key path must be Hashable", (Type))
473475

474476
// Selector expressions.
475477
ERROR(expr_selector_no_objc_runtime,none,

include/swift/AST/Expr.h

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4608,27 +4608,30 @@ class KeyPathExpr : public Expr {
46084608

46094609
llvm::PointerIntPair<Expr *, 3, Kind> SubscriptIndexExprAndKind;
46104610
ArrayRef<Identifier> SubscriptLabels;
4611+
ArrayRef<ProtocolConformanceRef> SubscriptHashableConformances;
46114612
Type ComponentType;
46124613
SourceLoc Loc;
46134614

46144615
explicit Component(ASTContext *ctxForCopyingLabels,
46154616
DeclNameOrRef decl,
46164617
Expr *indexExpr,
46174618
ArrayRef<Identifier> subscriptLabels,
4619+
ArrayRef<ProtocolConformanceRef> indexHashables,
46184620
Kind kind,
46194621
Type type,
46204622
SourceLoc loc);
46214623

46224624
public:
46234625
Component()
4624-
: Component(nullptr, {}, nullptr, {}, Kind::Invalid, Type(), SourceLoc())
4626+
: Component(nullptr, {}, nullptr, {}, {}, Kind::Invalid,
4627+
Type(), SourceLoc())
46254628
{}
46264629

46274630
/// Create an unresolved component for a property.
46284631
static Component forUnresolvedProperty(DeclName UnresolvedName,
46294632
SourceLoc Loc) {
46304633
return Component(nullptr,
4631-
UnresolvedName, nullptr, {},
4634+
UnresolvedName, nullptr, {}, {},
46324635
Kind::UnresolvedProperty,
46334636
Type(),
46344637
Loc);
@@ -4654,21 +4657,22 @@ class KeyPathExpr : public Expr {
46544657
SourceLoc loc) {
46554658

46564659
return Component(&context,
4657-
{}, index, subscriptLabels, Kind::UnresolvedSubscript,
4660+
{}, index, subscriptLabels, {},
4661+
Kind::UnresolvedSubscript,
46584662
Type(), loc);
46594663
}
46604664

46614665
/// Create an unresolved optional force `!` component.
46624666
static Component forUnresolvedOptionalForce(SourceLoc BangLoc) {
4663-
return Component(nullptr, {}, nullptr, {},
4667+
return Component(nullptr, {}, nullptr, {}, {},
46644668
Kind::OptionalForce,
46654669
Type(),
46664670
BangLoc);
46674671
}
46684672

46694673
/// Create an unresolved optional chain `?` component.
46704674
static Component forUnresolvedOptionalChain(SourceLoc QuestionLoc) {
4671-
return Component(nullptr, {}, nullptr, {},
4675+
return Component(nullptr, {}, nullptr, {}, {},
46724676
Kind::OptionalChain,
46734677
Type(),
46744678
QuestionLoc);
@@ -4678,42 +4682,44 @@ class KeyPathExpr : public Expr {
46784682
static Component forProperty(ConcreteDeclRef property,
46794683
Type propertyType,
46804684
SourceLoc loc) {
4681-
return Component(nullptr, property, nullptr, {},
4685+
return Component(nullptr, property, nullptr, {}, {},
46824686
Kind::Property,
46834687
propertyType,
46844688
loc);
46854689
}
46864690

46874691
/// Create a component for a subscript.
46884692
static Component forSubscript(ASTContext &ctx,
4689-
ConcreteDeclRef subscript,
4690-
SourceLoc lSquareLoc,
4691-
ArrayRef<Expr *> indexArgs,
4692-
ArrayRef<Identifier> indexArgLabels,
4693-
ArrayRef<SourceLoc> indexArgLabelLocs,
4694-
SourceLoc rSquareLoc,
4695-
Expr *trailingClosure,
4696-
Type elementType);
4693+
ConcreteDeclRef subscript,
4694+
SourceLoc lSquareLoc,
4695+
ArrayRef<Expr *> indexArgs,
4696+
ArrayRef<Identifier> indexArgLabels,
4697+
ArrayRef<SourceLoc> indexArgLabelLocs,
4698+
SourceLoc rSquareLoc,
4699+
Expr *trailingClosure,
4700+
Type elementType,
4701+
ArrayRef<ProtocolConformanceRef> indexHashables);
46974702

46984703
/// Create a component for a subscript.
46994704
///
47004705
/// You shouldn't add new uses of this overload; use the one that takes a
47014706
/// list of index arguments.
47024707
static Component forSubscriptWithPrebuiltIndexExpr(
47034708
ConcreteDeclRef subscript, Expr *index, ArrayRef<Identifier> labels,
4704-
Type elementType, SourceLoc loc);
4709+
Type elementType, SourceLoc loc,
4710+
ArrayRef<ProtocolConformanceRef> indexHashables);
47054711

47064712
/// Create an optional-forcing `!` component.
47074713
static Component forOptionalForce(Type forcedType, SourceLoc bangLoc) {
4708-
return Component(nullptr, {}, nullptr, {},
4714+
return Component(nullptr, {}, nullptr, {}, {},
47094715
Kind::OptionalForce, forcedType,
47104716
bangLoc);
47114717
}
47124718

47134719
/// Create an optional-chaining `?` component.
47144720
static Component forOptionalChain(Type unwrappedType,
47154721
SourceLoc questionLoc) {
4716-
return Component(nullptr, {}, nullptr, {},
4722+
return Component(nullptr, {}, nullptr, {}, {},
47174723
Kind::OptionalChain, unwrappedType,
47184724
questionLoc);
47194725
}
@@ -4722,7 +4728,7 @@ class KeyPathExpr : public Expr {
47224728
/// syntax but may appear when the non-optional result of an optional chain
47234729
/// is implicitly wrapped.
47244730
static Component forOptionalWrap(Type wrappedType) {
4725-
return Component(nullptr, {}, nullptr, {},
4731+
return Component(nullptr, {}, nullptr, {}, {},
47264732
Kind::OptionalWrap, wrappedType,
47274733
SourceLoc());
47284734
}
@@ -4789,6 +4795,26 @@ class KeyPathExpr : public Expr {
47894795
llvm_unreachable("no subscript labels for this kind");
47904796
}
47914797
}
4798+
4799+
ArrayRef<ProtocolConformanceRef>
4800+
getSubscriptIndexHashableConformances() const {
4801+
switch (getKind()) {
4802+
case Kind::Subscript:
4803+
return SubscriptHashableConformances;
4804+
4805+
case Kind::UnresolvedSubscript:
4806+
case Kind::Invalid:
4807+
case Kind::OptionalChain:
4808+
case Kind::OptionalWrap:
4809+
case Kind::OptionalForce:
4810+
case Kind::UnresolvedProperty:
4811+
case Kind::Property:
4812+
llvm_unreachable("no hashable conformances for this kind");
4813+
}
4814+
}
4815+
4816+
void setSubscriptIndexHashableConformances(
4817+
ArrayRef<ProtocolConformanceRef> hashables);
47924818

47934819
DeclName getUnresolvedDeclName() const {
47944820
switch (getKind()) {

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,6 @@ namespace swift {
238238
/// Diagnose uses of NSCoding with classes that have unstable mangled names.
239239
bool EnableNSKeyedArchiverDiagnostics = true;
240240

241-
/// Enable keypath components that aren't fully implemented.
242-
bool EnableExperimentalKeyPathComponents = false;
243-
244241
/// When a conversion from String to Substring fails, emit a fix-it to append
245242
/// the void subscript '[]'.
246243
/// FIXME: Remove this flag when void subscripts are implemented.

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ NODE(InfixOperator)
9797
CONTEXT_NODE(Initializer)
9898
NODE(KeyPathGetterThunkHelper)
9999
NODE(KeyPathSetterThunkHelper)
100+
NODE(KeyPathEqualsThunkHelper)
101+
NODE(KeyPathHashThunkHelper)
100102
NODE(LazyProtocolWitnessTableAccessor)
101103
NODE(LazyProtocolWitnessTableCacheVariable)
102104
NODE(LocalDeclName)

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,6 @@ def enable_experimental_property_behaviors :
279279
Flag<["-"], "enable-experimental-property-behaviors">,
280280
HelpText<"Enable experimental property behaviors">;
281281

282-
def enable_experimental_keypath_components :
283-
Flag<["-"], "enable-experimental-keypath-components">,
284-
HelpText<"Enable unimplemented keypath component kinds">;
285-
286282
def enable_deserialization_recovery :
287283
Flag<["-"], "enable-deserialization-recovery">,
288284
HelpText<"Attempt to recover from missing xrefs (etc) in swiftmodules">;

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,10 @@ FUNCTION(GetKeyPath, swift_getKeyPath, C_CC,
12211221
RETURNS(RefCountedPtrTy),
12221222
ARGS(Int8PtrTy, Int8PtrTy),
12231223
ATTRS(NoUnwind))
1224+
FUNCTION(CopyKeyPathTrivialIndices, swift_copyKeyPathTrivialIndices, DefaultCC,
1225+
RETURNS(VoidTy),
1226+
ARGS(Int8PtrTy, Int8PtrTy, SizeTy),
1227+
ATTRS(NoUnwind))
12241228

12251229
#if SWIFT_OBJC_INTEROP || !defined(SWIFT_RUNTIME_GENERATE_GLOBAL_SYMBOLS)
12261230

include/swift/SIL/SILBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,10 @@ class SILBuilder {
490490
KeyPathInst *createKeyPath(SILLocation Loc,
491491
KeyPathPattern *Pattern,
492492
SubstitutionList Subs,
493+
ArrayRef<SILValue> Args,
493494
SILType Ty) {
494495
return insert(KeyPathInst::create(getSILDebugLocation(Loc),
495-
Pattern, Subs, Ty, F));
496+
Pattern, Subs, Args, Ty, F));
496497
}
497498

498499
/// Convenience function for calling emitLoad on the type lowering for

include/swift/SIL/SILCloner.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,10 +2298,15 @@ void SILCloner<ImplClass>::visitObjCProtocolInst(ObjCProtocolInst *Inst) {
22982298
template <typename ImplClass>
22992299
void SILCloner<ImplClass>::visitKeyPathInst(KeyPathInst *Inst) {
23002300
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2301+
SmallVector<SILValue, 4> opValues;
2302+
for (auto &op : Inst->getAllOperands())
2303+
opValues.push_back(getOpValue(op.get()));
2304+
23012305
doPostProcess(Inst, getBuilder().createKeyPath(
23022306
getOpLocation(Inst->getLoc()),
23032307
Inst->getPattern(),
23042308
getOpSubstitutions(Inst->getSubstitutions()),
2309+
opValues,
23052310
getOpType(Inst->getType())));
23062311
}
23072312

0 commit comments

Comments
 (0)