Skip to content

Commit 0f6ff75

Browse files
committed
Add tests and isVariadic
1 parent d7f6e4a commit 0f6ff75

File tree

2 files changed

+42
-15
lines changed

2 files changed

+42
-15
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,7 +2560,8 @@ emitKeyPathRValueBase(SILGenFunction &subSGF,
25602560
return paramSubstValue;
25612561
}
25622562

2563-
using IndexTypePair = std::pair<CanType, SILType>;
2563+
/// formal, lowered, isVariadic
2564+
using IndexTypeTuple = std::tuple<CanType, SILType, bool>;
25642565

25652566
/// Helper function to load the captured indexes out of a key path component
25662567
/// in order to invoke the accessors on that key path. A component with captured
@@ -2570,7 +2571,7 @@ using IndexTypePair = std::pair<CanType, SILType>;
25702571
static PreparedArguments
25712572
loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc,
25722573
AbstractStorageDecl *storage,
2573-
ArrayRef<IndexTypePair> indexes,
2574+
ArrayRef<IndexTypeTuple> indexes,
25742575
SILValue pointer) {
25752576
// If not a subscript, do nothing.
25762577
if (!isa<SubscriptDecl>(storage))
@@ -2579,7 +2580,7 @@ loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc,
25792580
SmallVector<AnyFunctionType::Param, 8> indexParams;
25802581
for (auto &elt : indexes) {
25812582
// FIXME: Varargs?
2582-
indexParams.emplace_back(SGF.F.mapTypeIntoContext(elt.first));
2583+
indexParams.emplace_back(SGF.F.mapTypeIntoContext(std::get<0>(elt)));
25832584
}
25842585

25852586
PreparedArguments indexValues(indexParams);
@@ -2602,12 +2603,12 @@ loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc,
26022603
if (indexes.size() > 1) {
26032604
eltAddr = SGF.B.createTupleElementAddr(loc, eltAddr, i);
26042605
}
2605-
auto ty = SGF.F.mapTypeIntoContext(indexes[i].second);
2606+
auto ty = SGF.F.mapTypeIntoContext(std::get<1>(indexes[i]));
26062607
auto value = SGF.emitLoad(loc, eltAddr,
26072608
SGF.getTypeLowering(ty),
26082609
SGFContext(), IsNotTake);
26092610
auto substType =
2610-
SGF.F.mapTypeIntoContext(indexes[i].first)->getCanonicalType();
2611+
SGF.F.mapTypeIntoContext(std::get<0>(indexes[i]))->getCanonicalType();
26112612
indexValues.add(loc, RValue(SGF, loc, substType, value));
26122613
}
26132614

@@ -2629,7 +2630,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
26292630
SubstitutionMap subs,
26302631
GenericEnvironment *genericEnv,
26312632
ResilienceExpansion expansion,
2632-
ArrayRef<IndexTypePair> indexes,
2633+
ArrayRef<IndexTypeTuple> indexes,
26332634
CanType baseType,
26342635
CanType propertyType) {
26352636
// If the storage declaration is from a protocol, chase the override chain
@@ -2767,7 +2768,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM,
27672768
SubstitutionMap subs,
27682769
GenericEnvironment *genericEnv,
27692770
ResilienceExpansion expansion,
2770-
ArrayRef<IndexTypePair> indexes,
2771+
ArrayRef<IndexTypeTuple> indexes,
27712772
CanType baseType,
27722773
CanType propertyType) {
27732774
// If the storage declaration is from a protocol, chase the override chain
@@ -3310,7 +3311,7 @@ getIdForKeyPathComponentComputedProperty(SILGenModule &SGM,
33103311
static void
33113312
lowerKeyPathSubscriptIndexTypes(
33123313
SILGenModule &SGM,
3313-
SmallVectorImpl<IndexTypePair> &indexPatterns,
3314+
SmallVectorImpl<IndexTypeTuple> &indexPatterns,
33143315
SubscriptDecl *subscript,
33153316
SubstitutionMap subscriptSubs,
33163317
ResilienceExpansion expansion,
@@ -3337,22 +3338,23 @@ lowerKeyPathSubscriptIndexTypes(
33373338
indexLoweredTy = indexLoweredTy.mapTypeOutOfContext();
33383339
indexPatterns.push_back({indexTy->mapTypeOutOfContext()
33393340
->getCanonicalType(),
3340-
indexLoweredTy});
3341+
indexLoweredTy, index->isVariadic()});
33413342
}
33423343
};
33433344

33443345
static void lowerKeyPathSubscriptEqualsIndexPatterns(
33453346
SmallVectorImpl<KeyPathPatternComponent::Index> &indexPatterns,
3346-
ArrayRef<IndexTypePair> indexTypes,
3347+
ArrayRef<IndexTypeTuple> indexTypes,
33473348
ArrayRef<ProtocolConformanceRef> indexHashables, unsigned baseOperand,
33483349
SILGenModule &SGM, ResilienceExpansion expansion) {
33493350
for (unsigned i : indices(indexTypes)) {
33503351
CanType formalTy;
33513352
SILType loweredTy;
3352-
std::tie(formalTy, loweredTy) = indexTypes[i];
3353+
bool isVariadic;
3354+
std::tie(formalTy, loweredTy, isVariadic) = indexTypes[i];
33533355
auto hashable = indexHashables[i].mapConformanceOutOfContext();
33543356
// We have an array of variadic parameters...
3355-
if (!hashable.getConcrete()->getType()->isEqual(formalTy)) {
3357+
if (isVariadic) {
33563358
// Use the element type instead of the array type for hash/equals.
33573359
auto arrayTy = cast<BoundGenericStructType>(formalTy.getPointer());
33583360
auto elementTy = arrayTy->getGenericArgs()[0];
@@ -3384,12 +3386,13 @@ static void lowerKeyPathSubscriptEqualsIndexPatterns(
33843386

33853387
static void lowerKeyPathSubscriptIndexPatterns(
33863388
SmallVectorImpl<KeyPathPatternComponent::Index> &indexPatterns,
3387-
ArrayRef<IndexTypePair> indexTypes,
3389+
ArrayRef<IndexTypeTuple> indexTypes,
33883390
ArrayRef<ProtocolConformanceRef> indexHashables, unsigned &baseOperand) {
33893391
for (unsigned i : indices(indexTypes)) {
33903392
CanType formalTy;
33913393
SILType loweredTy;
3392-
std::tie(formalTy, loweredTy) = indexTypes[i];
3394+
bool isVariadic;
3395+
std::tie(formalTy, loweredTy, isVariadic) = indexTypes[i];
33933396
auto hashable = indexHashables[i].mapConformanceOutOfContext();
33943397

33953398
indexPatterns.push_back({baseOperand++, formalTy, loweredTy, hashable});
@@ -3531,7 +3534,7 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35313534
baseSubscriptTy->mapTypeOutOfContext()->getCanonicalType());
35323535
auto componentTy = baseSubscriptInterfaceTy.getResult();
35333536

3534-
SmallVector<IndexTypePair, 4> indexTypes;
3537+
SmallVector<IndexTypeTuple, 4> indexTypes;
35353538
lowerKeyPathSubscriptIndexTypes(*this, indexTypes,
35363539
decl, subs,
35373540
expansion,

test/SILGen/keypaths.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,18 @@ struct SubscriptDefaults5 {
369369
}
370370
}
371371

372+
struct SubscriptVariadic1 {
373+
subscript(x: Int...) -> Int { x[0] }
374+
}
375+
376+
struct SubscriptVariadic2 {
377+
subscript<T : ExpressibleByStringLiteral>(x: T...) -> T { x[0] }
378+
}
379+
380+
struct SubscriptVariadic3<T : ExpressibleByStringLiteral> {
381+
subscript(x: T...) -> T { x[0] }
382+
}
383+
372384
// CHECK-LABEL: sil hidden [ossa] @{{.*}}10subscripts1x1y1syx_q_SStSHRzSHR_r0_lF
373385
func subscripts<T: Hashable, U: Hashable>(x: T, y: U, s: String) {
374386
_ = \Subscripts<T>.[]
@@ -417,6 +429,18 @@ func subscripts<T: Hashable, U: Hashable>(x: T, y: U, s: String) {
417429
_ = \SubscriptDefaults4.[x: 0, y: 0]
418430
_ = \SubscriptDefaults5.[x: ""]
419431
_ = \SubscriptDefaults5.[x: "", y: ""]
432+
433+
_ = \SubscriptVariadic1.[1, 2, 3]
434+
_ = \SubscriptVariadic1.[1]
435+
_ = \SubscriptVariadic1.[]
436+
437+
_ = \SubscriptVariadic2.["", "1"]
438+
_ = \SubscriptVariadic2.[""]
439+
_ = \SubscriptVariadic2.["", #function]
440+
441+
_ = \SubscriptVariadic3<String>.[""]
442+
_ = \SubscriptVariadic3<String>.["", "1"]
443+
_ = \SubscriptVariadic3<String>.[]
420444
}
421445

422446
// CHECK-LABEL: sil hidden [ossa] @{{.*}}check_default_subscripts

0 commit comments

Comments
 (0)