@@ -118,6 +118,19 @@ static bool hasSingletonMetatype(CanType instanceType) {
118118
119119CaptureKind TypeConverter::getDeclCaptureKind (CapturedValue capture,
120120 TypeExpansionContext expansion) {
121+ if (auto *expr = capture.getPackElement ()) {
122+ auto contextTy = expr->getType ();
123+ auto &lowering = getTypeLowering (
124+ contextTy, TypeExpansionContext::noOpaqueTypeArchetypesSubstitution (
125+ expansion.getResilienceExpansion ()));
126+
127+ assert (!contextTy->isNoncopyable () && " Not implemented" );
128+ if (!lowering.isAddressOnly ())
129+ return CaptureKind::Constant;
130+
131+ return CaptureKind::Immutable;
132+ }
133+
121134 auto decl = capture.getDecl ();
122135 auto *var = cast<VarDecl>(decl);
123136 assert (var->hasStorage () &&
@@ -4241,7 +4254,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42414254
42424255 // Recursively collect transitive captures from captured local functions.
42434256 llvm::DenseSet<AnyFunctionRef> visitedFunctions;
4244- llvm::MapVector<ValueDecl*,CapturedValue> captures;
4257+
4258+ // FIXME: CapturedValue should just be a hash key
4259+ llvm::MapVector<VarDecl *, CapturedValue> varCaptures;
4260+ llvm::MapVector<PackElementExpr *, CapturedValue> packElementCaptures;
42454261
42464262 // If there is a capture of 'self' with dynamic 'Self' type, it goes last so
42474263 // that IRGen can pass dynamic 'Self' metadata.
@@ -4259,12 +4275,23 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42594275 std::function<void (SILDeclRef)> collectConstantCaptures;
42604276
42614277 auto recordCapture = [&](CapturedValue capture) {
4262- ValueDecl *value = capture.getDecl ();
4263- auto existing = captures.find (value);
4264- if (existing != captures.end ()) {
4265- existing->second = existing->second .mergeFlags (capture);
4278+ if (auto *expr = capture.getPackElement ()) {
4279+ auto existing = packElementCaptures.find (expr);
4280+ if (existing != packElementCaptures.end ()) {
4281+ existing->second = existing->second .mergeFlags (capture.getFlags ());
4282+ } else {
4283+ packElementCaptures.insert (std::pair<PackElementExpr *, CapturedValue>(
4284+ expr, capture));
4285+ }
42664286 } else {
4267- captures.insert (std::pair<ValueDecl *, CapturedValue>(value, capture));
4287+ VarDecl *value = cast<VarDecl>(capture.getDecl ());
4288+ auto existing = varCaptures.find (value);
4289+ if (existing != varCaptures.end ()) {
4290+ existing->second = existing->second .mergeFlags (capture.getFlags ());
4291+ } else {
4292+ varCaptures.insert (std::pair<VarDecl *, CapturedValue>(
4293+ value, capture));
4294+ }
42684295 }
42694296 };
42704297
@@ -4284,6 +4311,11 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42844311 }
42854312
42864313 for (auto capture : captureInfo.getCaptures ()) {
4314+ if (capture.isPackElement ()) {
4315+ recordCapture (capture);
4316+ continue ;
4317+ }
4318+
42874319 if (!capture.isLocalCapture ())
42884320 continue ;
42894321
@@ -4398,7 +4430,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
43984430 // If we've already captured the same value already, just merge
43994431 // flags.
44004432 if (selfCapture && selfCapture->getDecl () == capture.getDecl ()) {
4401- selfCapture = selfCapture->mergeFlags (capture);
4433+ selfCapture = selfCapture->mergeFlags (capture. getFlags () );
44024434 continue ;
44034435
44044436 // Otherwise, record the canonical self capture. It will appear
@@ -4492,7 +4524,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
44924524 collectConstantCaptures (fn);
44934525
44944526 SmallVector<CapturedValue, 4 > resultingCaptures;
4495- for (auto capturePair : captures) {
4527+ for (auto capturePair : varCaptures) {
4528+ resultingCaptures.push_back (capturePair.second );
4529+ }
4530+ for (auto capturePair : packElementCaptures) {
44964531 resultingCaptures.push_back (capturePair.second );
44974532 }
44984533
@@ -4511,7 +4546,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
45114546 resultingCaptures.push_back (*selfCapture);
45124547 }
45134548
4514- // Cache the uniqued set of transitive captures .
4549+ // Cache the result .
45154550 CaptureInfo info (Context, resultingCaptures,
45164551 capturesDynamicSelf, capturesOpaqueValue,
45174552 capturesGenericParams, genericEnv.getArrayRef ());
0 commit comments