@@ -4219,7 +4219,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4219
4219
4220
4220
// Recursively collect transitive captures from captured local functions.
4221
4221
llvm::DenseSet<AnyFunctionRef> visitedFunctions;
4222
- llvm::MapVector<ValueDecl*,CapturedValue> captures;
4222
+
4223
+ // FIXME: CapturedValue should just be a hash key
4224
+ llvm::MapVector<VarDecl *, CapturedValue> varCaptures;
4225
+ llvm::MapVector<PackElementExpr *, CapturedValue> packElementCaptures;
4223
4226
4224
4227
// If there is a capture of 'self' with dynamic 'Self' type, it goes last so
4225
4228
// that IRGen can pass dynamic 'Self' metadata.
@@ -4236,6 +4239,27 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4236
4239
std::function<void (AnyFunctionRef)> collectFunctionCaptures;
4237
4240
std::function<void (SILDeclRef)> collectConstantCaptures;
4238
4241
4242
+ auto recordCapture = [&](CapturedValue capture) {
4243
+ if (auto *expr = capture.getPackElement ()) {
4244
+ auto existing = packElementCaptures.find (expr);
4245
+ if (existing != packElementCaptures.end ()) {
4246
+ existing->second = existing->second .mergeFlags (capture.getFlags ());
4247
+ } else {
4248
+ packElementCaptures.insert (std::pair<PackElementExpr *, CapturedValue>(
4249
+ expr, capture));
4250
+ }
4251
+ } else {
4252
+ VarDecl *value = cast<VarDecl>(capture.getDecl ());
4253
+ auto existing = varCaptures.find (value);
4254
+ if (existing != varCaptures.end ()) {
4255
+ existing->second = existing->second .mergeFlags (capture.getFlags ());
4256
+ } else {
4257
+ varCaptures.insert (std::pair<VarDecl *, CapturedValue>(
4258
+ value, capture));
4259
+ }
4260
+ }
4261
+ };
4262
+
4239
4263
collectCaptures = [&](CaptureInfo captureInfo, DeclContext *dc) {
4240
4264
assert (captureInfo.hasBeenComputed ());
4241
4265
if (captureInfo.hasGenericParamCaptures ())
@@ -4255,6 +4279,11 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4255
4279
SmallVector<CapturedValue, 4 > localCaptures;
4256
4280
captureInfo.getLocalCaptures (localCaptures);
4257
4281
for (auto capture : localCaptures) {
4282
+ if (capture.isPackElement ()) {
4283
+ recordCapture (capture);
4284
+ continue ;
4285
+ }
4286
+
4258
4287
// If the capture is of another local function, grab its transitive
4259
4288
// captures instead.
4260
4289
if (auto capturedFn = getAnyFunctionRefFromCapture (capture)) {
@@ -4449,7 +4478,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4449
4478
collectConstantCaptures (fn);
4450
4479
4451
4480
SmallVector<CapturedValue, 4 > resultingCaptures;
4452
- for (auto capturePair : captures) {
4481
+ for (auto capturePair : varCaptures) {
4482
+ resultingCaptures.push_back (capturePair.second );
4483
+ }
4484
+ for (auto capturePair : packElementCaptures) {
4453
4485
resultingCaptures.push_back (capturePair.second );
4454
4486
}
4455
4487
@@ -4468,7 +4500,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4468
4500
resultingCaptures.push_back (*selfCapture);
4469
4501
}
4470
4502
4471
- // Cache the uniqued set of transitive captures .
4503
+ // Cache the result .
4472
4504
CaptureInfo info (Context, resultingCaptures,
4473
4505
capturesDynamicSelf, capturesOpaqueValue,
4474
4506
capturesGenericParams, genericEnv.getArrayRef ());
0 commit comments