@@ -2983,6 +2983,11 @@ emitKeyPathRValueBase(SILGenFunction &subSGF,
2983
2983
CanType &baseType,
2984
2984
SubstitutionList &subs,
2985
2985
SmallVectorImpl<Substitution> &subsBuf) {
2986
+ // If the storage is at global scope, then the base value () is a formality.
2987
+ // There no real argument to pass to the underlying accessors.
2988
+ if (!storage->getDeclContext ()->isTypeContext ())
2989
+ return ManagedValue ();
2990
+
2986
2991
auto paramOrigValue = subSGF.emitManagedRValueWithCleanup (paramArg);
2987
2992
auto paramSubstValue = subSGF.emitOrigToSubstValue (loc, paramOrigValue,
2988
2993
AbstractionPattern::getOpaque (),
@@ -3147,15 +3152,15 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
3147
3152
3148
3153
SmallVector<Substitution, 2 > subsBuf;
3149
3154
3150
- auto paramSubstValue = emitKeyPathRValueBase (subSGF, property,
3155
+ auto baseSubstValue = emitKeyPathRValueBase (subSGF, property,
3151
3156
loc, baseArg,
3152
3157
baseType, subs, subsBuf);
3153
3158
3154
3159
RValue indexValue = loadIndexValuesForKeyPathComponent (subSGF, loc,
3155
3160
indexes,
3156
3161
indexPtrArg);
3157
3162
3158
- auto resultSubst = subSGF.emitRValueForStorageLoad (loc, paramSubstValue ,
3163
+ auto resultSubst = subSGF.emitRValueForStorageLoad (loc, baseSubstValue ,
3159
3164
baseType, /* super*/ false ,
3160
3165
property, std::move (indexValue),
3161
3166
subs, AccessSemantics::Ordinary,
@@ -3448,6 +3453,11 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM,
3448
3453
auto equatable = *subMap
3449
3454
.lookupConformance (CanType (hashableSig->getGenericParams ()[0 ]),
3450
3455
equatableProtocol);
3456
+
3457
+ assert (equatable.isAbstract () == hashable.isAbstract ());
3458
+ if (equatable.isConcrete ())
3459
+ assert (equatable.getConcrete ()->getType ()->isEqual (
3460
+ hashable.getConcrete ()->getType ()));
3451
3461
auto equatableSub = Substitution (formalTy,
3452
3462
C.AllocateCopy (ArrayRef<ProtocolConformanceRef>(equatable)));
3453
3463
@@ -3690,15 +3700,21 @@ lowerKeyPathSubscriptIndexPatterns(
3690
3700
bool &needsGenericContext) {
3691
3701
// Capturing an index value dependent on the generic context means we
3692
3702
// need the generic context captured in the key path.
3693
- auto subMap =
3694
- subscript->getGenericSignature ()->getSubstitutionMap (subscriptSubs);
3695
- auto subscriptSubstTy = subscript->getInterfaceType ().subst (subMap);
3703
+ auto subscriptSubstTy = subscript->getInterfaceType ();
3704
+ SubstitutionMap subMap;
3705
+ auto sig = subscript->getGenericSignature ();
3706
+ if (sig) {
3707
+ subMap = sig->getSubstitutionMap (subscriptSubs);
3708
+ subscriptSubstTy = subscriptSubstTy.subst (subMap);
3709
+ }
3696
3710
needsGenericContext |= subscriptSubstTy->hasArchetype ();
3697
3711
3698
3712
unsigned i = 0 ;
3699
3713
for (auto *index : *subscript->getIndices ()) {
3700
- auto indexTy = index->getInterfaceType ().subst (subMap)
3701
- ->getCanonicalType ();
3714
+ auto indexTy = index->getInterfaceType ();
3715
+ if (sig) {
3716
+ indexTy = indexTy.subst (subMap);
3717
+ }
3702
3718
auto hashable = indexHashables[i++];
3703
3719
assert (hashable.isAbstract () ||
3704
3720
hashable.getConcrete ()->getType ()->isEqual (indexTy));
@@ -3718,20 +3734,24 @@ lowerKeyPathSubscriptIndexPatterns(
3718
3734
}
3719
3735
};
3720
3736
3721
- static KeyPathPatternComponent
3722
- emitKeyPathComponentForDecl (SILGenModule &SGM,
3723
- SILLocation loc,
3724
- GenericEnvironment *genericEnv,
3725
- unsigned &baseOperand,
3726
- bool &needsGenericContext,
3727
- SubstitutionList subs,
3728
- AbstractStorageDecl *storage,
3729
- ArrayRef<ProtocolConformanceRef> indexHashables,
3730
- CanType baseTy) {
3737
+ KeyPathPatternComponent
3738
+ SILGenModule::emitKeyPathComponentForDecl (SILLocation loc,
3739
+ GenericEnvironment *genericEnv,
3740
+ unsigned &baseOperand,
3741
+ bool &needsGenericContext,
3742
+ SubstitutionList subs,
3743
+ AbstractStorageDecl *storage,
3744
+ ArrayRef<ProtocolConformanceRef> indexHashables,
3745
+ CanType baseTy) {
3731
3746
if (auto var = dyn_cast<VarDecl>(storage)) {
3732
- auto componentTy = baseTy->getTypeOfMember (SGM.SwiftModule , var)
3733
- ->getReferenceStorageReferent ()
3734
- ->getCanonicalType ();
3747
+ CanType componentTy;
3748
+ if (!var->getDeclContext ()->isTypeContext ()) {
3749
+ componentTy = storage->getStorageInterfaceType ()->getCanonicalType ();
3750
+ } else {
3751
+ componentTy = baseTy->getTypeOfMember (SwiftModule, var)
3752
+ ->getReferenceStorageReferent ()
3753
+ ->getCanonicalType ();
3754
+ }
3735
3755
3736
3756
switch (auto strategy = var->getAccessStrategy (AccessSemantics::Ordinary,
3737
3757
AccessKind::ReadWrite)) {
@@ -3741,9 +3761,9 @@ emitKeyPathComponentForDecl(SILGenModule &SGM,
3741
3761
auto componentObjTy = componentTy->getWithoutSpecifierType ();
3742
3762
if (genericEnv)
3743
3763
componentObjTy = genericEnv->mapTypeIntoContext (componentObjTy);
3744
- auto storageTy = SGM. Types .getSubstitutedStorageType (var,
3764
+ auto storageTy = Types.getSubstitutedStorageType (var,
3745
3765
componentObjTy);
3746
- auto opaqueTy = SGM. Types
3766
+ auto opaqueTy = Types
3747
3767
.getLoweredType (AbstractionPattern::getOpaque (), componentObjTy);
3748
3768
3749
3769
if (storageTy.getAddressType () == opaqueTy.getAddressType ()) {
@@ -3756,17 +3776,17 @@ emitKeyPathComponentForDecl(SILGenModule &SGM,
3756
3776
case AccessStrategy::DispatchToAccessor: {
3757
3777
// We need thunks to bring the getter and setter to the right signature
3758
3778
// expected by the key path runtime.
3759
- auto id = getIdForKeyPathComponentComputedProperty (SGM , var,
3779
+ auto id = getIdForKeyPathComponentComputedProperty (* this , var,
3760
3780
strategy);
3761
- auto getter = getOrCreateKeyPathGetter (SGM , loc,
3781
+ auto getter = getOrCreateKeyPathGetter (* this , loc,
3762
3782
var, subs,
3763
3783
strategy,
3764
3784
needsGenericContext ? genericEnv : nullptr ,
3765
3785
{},
3766
3786
baseTy, componentTy);
3767
3787
3768
3788
if (var->isSettable (var->getDeclContext ())) {
3769
- auto setter = getOrCreateKeyPathSetter (SGM , loc,
3789
+ auto setter = getOrCreateKeyPathSetter (* this , loc,
3770
3790
var, subs,
3771
3791
strategy,
3772
3792
needsGenericContext ? genericEnv : nullptr ,
@@ -3796,28 +3816,30 @@ emitKeyPathComponentForDecl(SILGenModule &SGM,
3796
3816
auto componentTy = baseSubscriptInterfaceTy.getResult ();
3797
3817
3798
3818
SmallVector<KeyPathPatternComponent::Index, 4 > indexPatterns;
3799
- lowerKeyPathSubscriptIndexPatterns (SGM , indexPatterns,
3819
+ lowerKeyPathSubscriptIndexPatterns (* this , indexPatterns,
3800
3820
decl, subs, indexHashables,
3801
3821
baseOperand,
3802
3822
needsGenericContext);
3803
3823
3804
3824
SILFunction *indexEquals = nullptr , *indexHash = nullptr ;
3805
- getOrCreateKeyPathEqualsAndHash (SGM, loc,
3825
+ // TODO: Property descriptors for external key paths should get their
3826
+ // equality and hashing from the client.
3827
+ getOrCreateKeyPathEqualsAndHash (*this , loc,
3806
3828
needsGenericContext ? genericEnv : nullptr ,
3807
3829
indexPatterns,
3808
3830
indexEquals, indexHash);
3809
3831
3810
- auto id = getIdForKeyPathComponentComputedProperty (SGM , decl, strategy);
3811
- auto getter = getOrCreateKeyPathGetter (SGM , loc,
3832
+ auto id = getIdForKeyPathComponentComputedProperty (* this , decl, strategy);
3833
+ auto getter = getOrCreateKeyPathGetter (* this , loc,
3812
3834
decl, subs,
3813
3835
strategy,
3814
3836
needsGenericContext ? genericEnv : nullptr ,
3815
3837
indexPatterns,
3816
3838
baseTy, componentTy);
3817
3839
3818
- auto indexPatternsCopy = SGM. getASTContext ().AllocateCopy (indexPatterns);
3840
+ auto indexPatternsCopy = getASTContext ().AllocateCopy (indexPatterns);
3819
3841
if (decl->isSettable ()) {
3820
- auto setter = getOrCreateKeyPathSetter (SGM , loc,
3842
+ auto setter = getOrCreateKeyPathSetter (* this , loc,
3821
3843
decl, subs,
3822
3844
strategy,
3823
3845
needsGenericContext ? genericEnv : nullptr ,
@@ -3952,7 +3974,7 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
3952
3974
} else {
3953
3975
unsigned numOperands = operands.size ();
3954
3976
loweredComponents.push_back (
3955
- emitKeyPathComponentForDecl ( SGF.SGM , SILLocation (E),
3977
+ SGF.SGM . emitKeyPathComponentForDecl ( SILLocation (E),
3956
3978
SGF.F .getGenericEnvironment (),
3957
3979
numOperands,
3958
3980
needsGenericContext,
0 commit comments