@@ -3929,10 +3929,23 @@ class SILTypeSubstituter :
3929
3929
CanGenericSignature Sig;
3930
3930
3931
3931
struct PackExpansion {
3932
- CanType ExpandedShape;
3932
+ // / The shape class of pack parameters that are expanded by this
3933
+ // / expansion. Set during construction and not changed.
3934
+ CanType OrigShapeClass;
3935
+
3936
+ // / The count type of the pack expansion in the current lane of
3937
+ // / expansion, if any. Pack elements in this lane should be
3938
+ // / expansions with this shape.
3939
+ CanType SubstPackExpansionCount;
3940
+
3941
+ // / The index of the current lane of expansion. Basic
3942
+ // / substitution of pack parameters with the same shape as
3943
+ // / OrigShapeClass should yield a pack, and lanewise
3944
+ // / substitution should produce this element of that pack.
3933
3945
unsigned Index;
3934
3946
3935
- PackExpansion (CanType shape) : ExpandedShape(shape), Index(0 ) {}
3947
+ PackExpansion (CanType origShapeClass)
3948
+ : OrigShapeClass(origShapeClass), Index(0 ) {}
3936
3949
};
3937
3950
SmallVector<PackExpansion> ActivePackExpansions;
3938
3951
@@ -4253,7 +4266,7 @@ class SILTypeSubstituter :
4253
4266
4254
4267
CanType visitPackExpansionType (CanPackExpansionType origType) {
4255
4268
CanType patternType = visit (origType.getPatternType ());
4256
- CanType countType = visit (origType.getCountType ());
4269
+ CanType countType = substASTType (origType.getCountType ());
4257
4270
4258
4271
return CanType (PackExpansionType::get (patternType, countType));
4259
4272
}
@@ -4264,21 +4277,24 @@ class SILTypeSubstituter :
4264
4277
CanType origPatternType = origType.getPatternType ();
4265
4278
4266
4279
// Substitute the count type (as an AST type).
4267
- CanType substCountType = visitType (origCountType);
4280
+ CanType substCountType = substASTType (origCountType);
4268
4281
4269
4282
// If that produces a pack type, expand the pattern element-wise.
4270
4283
if (auto substCountPackType = dyn_cast<PackType>(substCountType)) {
4271
4284
// Set up for element-wise expansion.
4272
4285
ActivePackExpansions.emplace_back (origCountType);
4273
4286
4274
4287
for (CanType substCountEltType : substCountPackType.getElementTypes ()) {
4288
+ auto expansionType = dyn_cast<PackExpansionType>(substCountEltType);
4289
+ ActivePackExpansions.back ().SubstPackExpansionCount =
4290
+ (expansionType ? expansionType.getCountType () : CanType ());
4291
+
4275
4292
// Expand the pattern type in the element-wise context.
4276
4293
CanType expandedType = visit (origPatternType);
4277
4294
4278
4295
// Turn that into a pack expansion if appropriate for the
4279
4296
// count element.
4280
- if (auto expansionType =
4281
- dyn_cast<PackExpansionType>(substCountEltType)) {
4297
+ if (expansionType) {
4282
4298
expandedType =
4283
4299
CanPackExpansionType::get (expandedType,
4284
4300
expansionType.getCountType ());
@@ -4317,11 +4333,44 @@ class SILTypeSubstituter :
4317
4333
SmallVector<TupleTypeElt, 8 > substElts;
4318
4334
substElts.reserve (origType->getNumElements ());
4319
4335
for (auto &origElt : origType->getElements ()) {
4320
- auto substEltType = visit (CanType (origElt.getType ()));
4321
- substElts.push_back (origElt.getWithType (substEltType));
4336
+ CanType origEltType = CanType (origElt.getType ());
4337
+ if (auto origExpansion = dyn_cast<PackExpansionType>(origEltType)) {
4338
+ bool first = true ;
4339
+ substPackExpansion (origExpansion, [&](CanType substEltType) {
4340
+ auto substElt = origElt.getWithType (substEltType);
4341
+ if (first) {
4342
+ first = false ;
4343
+ } else {
4344
+ substElt = substElt.getWithoutName ();
4345
+ }
4346
+ substElts.push_back (substElt);
4347
+ });
4348
+ } else {
4349
+ auto substEltType = visit (origEltType);
4350
+ substElts.push_back (origElt.getWithType (substEltType));
4351
+ }
4322
4352
}
4353
+
4354
+ // Turn unlabeled singleton scalar tuples into their underlying types.
4355
+ // The AST type substituter doesn't actually implement this rule yet,
4356
+ // but we need to implement it in SIL in order to support testing,
4357
+ // since the type parser can't parse a singleton tuple.
4358
+ //
4359
+ // For compatibility with previous behavior, don't do this if the
4360
+ // original tuple type was singleton. AutoDiff apparently really
4361
+ // likes making singleton tuples.
4362
+ if (isParenType (substElts) && !isParenType (origType->getElements ()))
4363
+ return CanType (substElts[0 ].getType ());
4364
+
4323
4365
return CanType (TupleType::get (substElts, TC.Context ));
4324
4366
}
4367
+
4368
+ static bool isParenType (ArrayRef<TupleTypeElt> elts) {
4369
+ return (elts.size () == 1 &&
4370
+ !elts[0 ].hasName () &&
4371
+ !isa<PackExpansionType>(CanType (elts[0 ].getType ())));
4372
+ }
4373
+
4325
4374
// Block storage types need to substitute their capture type by these same
4326
4375
// rules.
4327
4376
CanType visitSILBlockStorageType (CanSILBlockStorageType origType) {
@@ -4375,11 +4424,21 @@ class SILTypeSubstituter :
4375
4424
[&](SubstitutableType *origType) -> Type {
4376
4425
auto substType = Subst (origType);
4377
4426
if (!substType) return substType;
4378
- auto substPackType = substType-> getAs <PackType>();
4427
+ auto substPackType = dyn_cast <PackType>(substType-> getCanonicalType () );
4379
4428
if (!substPackType) return substType;
4380
- auto index = getPackExpansionIndex (CanType (origType));
4381
- if (!index) return substType;
4382
- return substPackType->getElementType (*index);
4429
+ auto activeExpansion = getActivePackExpansion (CanType (origType));
4430
+ if (!activeExpansion) return substType;
4431
+ auto substEltType =
4432
+ substPackType.getElementType (activeExpansion->Index );
4433
+ auto substExpansion = dyn_cast<PackExpansionType>(substEltType);
4434
+ assert ((bool ) substExpansion ==
4435
+ (bool ) activeExpansion->SubstPackExpansionCount );
4436
+ if (substExpansion) {
4437
+ assert (hasSameShape (substExpansion.getCountType (),
4438
+ activeExpansion->SubstPackExpansionCount ));
4439
+ return substExpansion.getPatternType ();
4440
+ }
4441
+ return substEltType;
4383
4442
},
4384
4443
[&](CanType dependentType,
4385
4444
Type conformingReplacementType,
@@ -4388,23 +4447,27 @@ class SILTypeSubstituter :
4388
4447
conformingReplacementType,
4389
4448
conformingProtocol);
4390
4449
if (!conformance || !conformance.isPack ()) return conformance;
4391
- auto index = getPackExpansionIndex (dependentType);
4392
- if (!index ) return conformance;
4450
+ auto activeExpansion = getActivePackExpansion (dependentType);
4451
+ if (!activeExpansion ) return conformance;
4393
4452
auto pack = conformance.getPack ();
4394
- return pack->getPatternConformances ()[*index];
4453
+ auto substEltConf =
4454
+ pack->getPatternConformances ()[activeExpansion->Index ];
4455
+ // There isn't currently a ProtocolConformanceExpansion that
4456
+ // we would need to look through here.
4457
+ return substEltConf;
4395
4458
},
4396
4459
substOptions)->getCanonicalType ();
4397
4460
}
4398
4461
4399
- Optional< size_t > getPackExpansionIndex (CanType dependentType) {
4462
+ PackExpansion * getActivePackExpansion (CanType dependentType) {
4400
4463
// We push new expansions onto the end of this vector, and we
4401
4464
// want to honor the innermost expansion, so we have to traverse
4402
4465
// in it reverse.
4403
4466
for (auto &entry : reverse (ActivePackExpansions)) {
4404
- if (hasSameShape (dependentType, entry.ExpandedShape ))
4405
- return entry. Index ;
4467
+ if (hasSameShape (dependentType, entry.OrigShapeClass ))
4468
+ return & entry;
4406
4469
}
4407
- return None ;
4470
+ return nullptr ;
4408
4471
}
4409
4472
4410
4473
bool hasSameShape (CanType lhs, CanType rhs) {
0 commit comments