@@ -2063,7 +2063,7 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
2063
2063
2064
2064
// Recursively collect transitive captures from captured local functions.
2065
2065
llvm::DenseSet<AnyFunctionRef> visitedFunctions;
2066
- llvm::SetVector< CapturedValue> captures;
2066
+ llvm::MapVector<ValueDecl*, CapturedValue> captures;
2067
2067
2068
2068
// If there is a capture of 'self' with dynamic 'Self' type, it goes last so
2069
2069
// that IRGen can pass dynamic 'Self' metadata.
@@ -2143,23 +2143,55 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
2143
2143
goto capture_value;
2144
2144
}
2145
2145
}
2146
+
2147
+ if (!capturedVar->hasStorage ())
2148
+ continue ;
2149
+
2150
+ // We can always capture the storage in these cases.
2151
+ Type captureType = capturedVar->getType ();
2152
+ if (auto *metatypeType = captureType->getAs <MetatypeType>())
2153
+ captureType = metatypeType->getInstanceType ();
2154
+
2155
+ if (auto *selfType = captureType->getAs <DynamicSelfType>()) {
2156
+ captureType = selfType->getSelfType ();
2157
+
2158
+ // We're capturing a 'self' value with dynamic 'Self' type;
2159
+ // handle it specially.
2160
+ if (captureType->getClassOrBoundGenericClass ()) {
2161
+ if (selfCapture)
2162
+ selfCapture = selfCapture->mergeFlags (capture);
2163
+ else
2164
+ selfCapture = capture;
2165
+ continue ;
2166
+ }
2167
+ }
2146
2168
}
2147
-
2148
2169
capture_value:
2149
2170
// Collect non-function captures.
2150
- captures.insert (capture);
2171
+ ValueDecl *value = capture.getDecl ();
2172
+ auto existing = captures.find (value);
2173
+ if (existing != captures.end ()) {
2174
+ existing->second = existing->second .mergeFlags (capture);
2175
+ } else {
2176
+ captures.insert (std::pair<ValueDecl *, CapturedValue>(value, capture));
2177
+ }
2151
2178
}
2152
2179
};
2153
2180
collectFunctionCaptures (fn);
2154
2181
2182
+ SmallVector<CapturedValue, 4 > resultingCaptures;
2183
+ for (auto capturePair : captures) {
2184
+ resultingCaptures.push_back (capturePair.second );
2185
+ }
2186
+
2155
2187
// If we captured the dynamic 'Self' type and we have a 'self' value also,
2156
2188
// add it as the final capture. Otherwise, add a fake hidden capture for
2157
2189
// the dynamic 'Self' metatype.
2158
2190
if (selfCapture.hasValue ()) {
2159
- captures. insert (*selfCapture);
2191
+ resultingCaptures. push_back (*selfCapture);
2160
2192
} else if (capturesDynamicSelf) {
2161
2193
selfCapture = CapturedValue::getDynamicSelfMetadata ();
2162
- captures. insert (*selfCapture);
2194
+ resultingCaptures. push_back (*selfCapture);
2163
2195
}
2164
2196
2165
2197
// Cache the uniqued set of transitive captures.
@@ -2168,7 +2200,7 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
2168
2200
auto &cachedCaptures = inserted.first ->second ;
2169
2201
cachedCaptures.setGenericParamCaptures (capturesGenericParams);
2170
2202
cachedCaptures.setDynamicSelfType (capturesDynamicSelf);
2171
- cachedCaptures.setCaptures (Context.AllocateCopy (captures ));
2203
+ cachedCaptures.setCaptures (Context.AllocateCopy (resultingCaptures ));
2172
2204
2173
2205
return cachedCaptures;
2174
2206
}
0 commit comments