@@ -1855,8 +1855,34 @@ TypeConverter::getEffectiveGenericParamsForContext(DeclContext *dc) {
1855
1855
return dc->getGenericParamsOfContext ();
1856
1856
}
1857
1857
1858
+ GenericParamList *
1859
+ TypeConverter::getEffectiveGenericParams (AnyFunctionRef fn,
1860
+ CaptureInfo captureInfo) {
1861
+ auto dc = fn.getAsDeclContext ()->getParent ();
1862
+
1863
+ if (dc->isLocalContext () &&
1864
+ !captureInfo.hasGenericParamCaptures ()) {
1865
+ return nullptr ;
1866
+ }
1867
+
1868
+ return getEffectiveGenericParamsForContext (dc);
1869
+ }
1870
+
1858
1871
CanGenericSignature
1859
- TypeConverter::getEffectiveGenericSignatureForContext (DeclContext *dc) {
1872
+ TypeConverter::getEffectiveGenericSignature (AnyFunctionRef fn,
1873
+ CaptureInfo captureInfo) {
1874
+ auto dc = fn.getAsDeclContext ();
1875
+
1876
+ if (auto sig = dc->getGenericSignatureOfContext ())
1877
+ return sig->getCanonicalSignature ();
1878
+
1879
+ dc = dc->getParent ();
1880
+
1881
+ if (dc->isLocalContext () &&
1882
+ !captureInfo.hasGenericParamCaptures ()) {
1883
+ return nullptr ;
1884
+ }
1885
+
1860
1886
// Find the innermost context that has a generic parameter list.
1861
1887
// FIXME: This is wrong for generic local functions in generic contexts.
1862
1888
// Their GenericParamList is not semantically a child of the context
@@ -1876,11 +1902,16 @@ TypeConverter::getEffectiveGenericSignatureForContext(DeclContext *dc) {
1876
1902
CanAnyFunctionType
1877
1903
TypeConverter::getFunctionTypeWithCaptures (CanAnyFunctionType funcType,
1878
1904
AnyFunctionRef theClosure) {
1879
- auto parentContext = theClosure.getAsDeclContext ()->getParent ();
1880
- // Capture generic parameters from the enclosing context.
1881
- GenericParamList *genericParams
1882
- = getEffectiveGenericParamsForContext (parentContext);
1883
-
1905
+ // Get transitive closure of value captured by this function, and any
1906
+ // captured functions.
1907
+ auto captureInfo = getLoweredLocalCaptures (theClosure);
1908
+
1909
+ // Capture generic parameters from the enclosing context if necessary.
1910
+ GenericParamList *genericParams =
1911
+ getEffectiveGenericParams (theClosure, captureInfo);
1912
+
1913
+ // If we don't have any local captures (including function captures),
1914
+ // there's no context to apply.
1884
1915
if (!theClosure.getCaptureInfo ().hasLocalCaptures ()) {
1885
1916
if (!genericParams)
1886
1917
return adjustFunctionType (funcType,
@@ -1900,12 +1931,7 @@ TypeConverter::getFunctionTypeWithCaptures(CanAnyFunctionType funcType,
1900
1931
1901
1932
SmallVector<TupleTypeElt, 8 > inputFields;
1902
1933
1903
- // Note that the list of lowered local captures may be empty even if
1904
- // CaptureInfo::hasLocalCaptures() returned true. This is the case if e.g.
1905
- // a local function calls another local function which has no captures itself.
1906
- ArrayRef<CapturedValue> captures = getLoweredLocalCaptures (theClosure);
1907
-
1908
- for (auto capture : captures) {
1934
+ for (auto capture : captureInfo.getCaptures ()) {
1909
1935
auto VD = capture.getDecl ();
1910
1936
// A capture of a 'var' or 'inout' variable is done with the underlying
1911
1937
// object type.
@@ -1955,12 +1981,16 @@ TypeConverter::getFunctionTypeWithCaptures(CanAnyFunctionType funcType,
1955
1981
CanAnyFunctionType
1956
1982
TypeConverter::getFunctionInterfaceTypeWithCaptures (CanAnyFunctionType funcType,
1957
1983
AnyFunctionRef theClosure) {
1958
- auto context = theClosure.getAsDeclContext ();
1984
+ // Get transitive closure of value captured by this function, and any
1985
+ // captured functions.
1986
+ auto captureInfo = getLoweredLocalCaptures (theClosure);
1959
1987
1960
- // Capture generic parameters from the enclosing context.
1961
- CanGenericSignature genericSig
1962
- = getEffectiveGenericSignatureForContext (context );
1988
+ // Capture generic parameters from the enclosing context if necessary .
1989
+ CanGenericSignature genericSig = getEffectiveGenericSignature (theClosure,
1990
+ captureInfo );
1963
1991
1992
+ // If we don't have any local captures (including function captures),
1993
+ // there's no context to apply.
1964
1994
if (!theClosure.getCaptureInfo ().hasLocalCaptures ()) {
1965
1995
if (!genericSig)
1966
1996
return adjustFunctionType (funcType,
@@ -1978,12 +2008,7 @@ TypeConverter::getFunctionInterfaceTypeWithCaptures(CanAnyFunctionType funcType,
1978
2008
1979
2009
SmallVector<TupleTypeElt, 8 > inputFields;
1980
2010
1981
- // Note that the list of lowered local captures may be empty even if
1982
- // CaptureInfo::hasLocalCaptures() returned true. This is the case if e.g.
1983
- // a local function calls another local function which has no captures itself.
1984
- ArrayRef<CapturedValue> captures = getLoweredLocalCaptures (theClosure);
1985
-
1986
- for (auto capture : captures) {
2011
+ for (auto capture : captureInfo.getCaptures ()) {
1987
2012
// A capture of a 'var' or 'inout' variable is done with the underlying
1988
2013
// object type.
1989
2014
auto vd = capture.getDecl ();
@@ -2019,7 +2044,9 @@ TypeConverter::getFunctionInterfaceTypeWithCaptures(CanAnyFunctionType funcType,
2019
2044
TupleType::get (inputFields, Context)->getCanonicalType ();
2020
2045
2021
2046
// Map context archetypes out of the captures.
2022
- capturedInputs = getInterfaceTypeOutOfContext (capturedInputs, context);
2047
+ capturedInputs =
2048
+ getInterfaceTypeOutOfContext (capturedInputs,
2049
+ theClosure.getAsDeclContext ());
2023
2050
2024
2051
auto extInfo = AnyFunctionType::ExtInfo (FunctionType::Representation::Thin,
2025
2052
/* noreturn*/ false ,
@@ -2117,22 +2144,22 @@ TypeConverter::getConstantContextGenericParams(SILDeclRef c) {
2117
2144
ValueDecl *vd = c.loc .dyn_cast <ValueDecl *>();
2118
2145
2119
2146
// / Get the function generic params, including outer params.
2120
- auto getLocalFuncParams = [&](FuncDecl *func) -> GenericParamList * {
2121
- // FIXME: For local generic functions we need to chain the local generic
2122
- // context to the outer context.
2123
- if (auto GP = func->getGenericParamsOfContext ())
2124
- return GP;
2125
- return getEffectiveGenericParamsForContext (func->getParent ());
2126
- };
2127
-
2128
2147
switch (c.kind ) {
2129
2148
case SILDeclRef::Kind::Func: {
2130
2149
if (auto *ACE = c.getAbstractClosureExpr ()) {
2150
+ auto captureInfo = getLoweredLocalCaptures (ACE);
2151
+
2131
2152
// Closures are currently never natively generic.
2132
- return {getEffectiveGenericParamsForContext (ACE-> getParent () ), nullptr };
2153
+ return {getEffectiveGenericParams (ACE, captureInfo ), nullptr };
2133
2154
}
2134
2155
FuncDecl *func = cast<FuncDecl>(vd);
2135
- return {getLocalFuncParams (func), func->getGenericParams ()};
2156
+ // FIXME: For local generic functions we need to chain the local generic
2157
+ // context to the outer context.
2158
+ if (auto GP = func->getGenericParamsOfContext ())
2159
+ return {GP, func->getGenericParams ()};
2160
+ auto captureInfo = getLoweredLocalCaptures (func);
2161
+ return {getEffectiveGenericParams (func, captureInfo),
2162
+ func->getGenericParams ()};
2136
2163
}
2137
2164
case SILDeclRef::Kind::EnumElement: {
2138
2165
auto eltDecl = cast<EnumElementDecl>(vd);
@@ -2328,11 +2355,15 @@ getAnyFunctionRefFromCapture(CapturedValue capture) {
2328
2355
return None;
2329
2356
}
2330
2357
2331
- ArrayRef<CapturedValue>
2358
+ CaptureInfo
2332
2359
TypeConverter::getLoweredLocalCaptures (AnyFunctionRef fn) {
2333
2360
// First, bail out if there are no local captures at all.
2334
- if (!fn.getCaptureInfo ().hasLocalCaptures ())
2335
- return {};
2361
+ if (!fn.getCaptureInfo ().hasLocalCaptures ()) {
2362
+ CaptureInfo info;
2363
+ info.setGenericParamCaptures (
2364
+ fn.getCaptureInfo ().hasGenericParamCaptures ());
2365
+ return info;
2366
+ };
2336
2367
2337
2368
// See if we've cached the lowered capture list for this function.
2338
2369
auto found = LoweredCaptures.find (fn);
@@ -2342,12 +2373,16 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
2342
2373
// Recursively collect transitive captures from captured local functions.
2343
2374
llvm::DenseSet<AnyFunctionRef> visitedFunctions;
2344
2375
llvm::SetVector<CapturedValue> captures;
2376
+ bool capturesGenericParams = false ;
2345
2377
2346
2378
std::function<void (AnyFunctionRef)> collectFunctionCaptures
2347
2379
= [&](AnyFunctionRef curFn) {
2348
2380
if (!visitedFunctions.insert (curFn).second )
2349
2381
return ;
2350
2382
2383
+ if (curFn.getCaptureInfo ().hasGenericParamCaptures ())
2384
+ capturesGenericParams = true ;
2385
+
2351
2386
SmallVector<CapturedValue, 4 > localCaptures;
2352
2387
curFn.getCaptureInfo ().getLocalCaptures (localCaptures);
2353
2388
for (auto capture : localCaptures) {
@@ -2401,11 +2436,11 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
2401
2436
collectFunctionCaptures (fn);
2402
2437
2403
2438
// Cache the uniqued set of transitive captures.
2404
- auto inserted = LoweredCaptures.insert ({fn, {} });
2439
+ auto inserted = LoweredCaptures.insert ({fn, CaptureInfo () });
2405
2440
assert (inserted.second && " already in map?!" );
2406
2441
auto &cachedCaptures = inserted.first ->second ;
2407
- std::copy (captures. begin (), captures. end (),
2408
- std::back_inserter ( cachedCaptures));
2442
+ cachedCaptures. setGenericParamCaptures (capturesGenericParams);
2443
+ cachedCaptures. setCaptures (Context. AllocateCopy (captures ));
2409
2444
2410
2445
return cachedCaptures;
2411
2446
}
0 commit comments