|
20 | 20 |
|
21 | 21 | #include "swift/AST/GenericEnvironment.h"
|
22 | 22 | #include "swift/AST/SILLayout.h"
|
| 23 | +#include "swift/AST/LifetimeDependence.h" |
23 | 24 |
|
24 | 25 | namespace swift {
|
25 | 26 |
|
@@ -333,11 +334,37 @@ case TypeKind::Id:
|
333 | 334 | transErrorResult = result;
|
334 | 335 | }
|
335 | 336 |
|
336 |
| - if (!changed) return t; |
| 337 | + if (!changed) { |
| 338 | + return t; |
| 339 | + } |
| 340 | + |
| 341 | + // Lifetime dependencies get eliminated if their target type was |
| 342 | + // substituted with an escapable type. |
| 343 | + auto extInfo = fnTy->getExtInfo(); |
| 344 | + if (!extInfo.getLifetimeDependencies().empty()) { |
| 345 | + SmallVector<LifetimeDependenceInfo, 2> substDependenceInfos; |
| 346 | + bool didRemoveLifetimeDependencies |
| 347 | + = filterEscapableLifetimeDependencies(GenericSignature(), |
| 348 | + extInfo.getLifetimeDependencies(), |
| 349 | + substDependenceInfos, |
| 350 | + [&](unsigned targetIndex) { |
| 351 | + if (targetIndex >= transInterfaceParams.size()) { |
| 352 | + // Target is a return type. |
| 353 | + return transInterfaceResults[targetIndex - transInterfaceParams.size()] |
| 354 | + .getInterfaceType(); |
| 355 | + } else { |
| 356 | + // Target is a parameter. |
| 357 | + return transInterfaceParams[targetIndex].getInterfaceType(); |
| 358 | + } |
| 359 | + }); |
| 360 | + if (didRemoveLifetimeDependencies) { |
| 361 | + extInfo = extInfo.withLifetimeDependencies(substDependenceInfos); |
| 362 | + } |
| 363 | + } |
337 | 364 |
|
338 | 365 | return SILFunctionType::get(
|
339 | 366 | fnTy->getInvocationGenericSignature(),
|
340 |
| - fnTy->getExtInfo(), |
| 367 | + extInfo, |
341 | 368 | fnTy->getCoroutineKind(),
|
342 | 369 | fnTy->getCalleeConvention(),
|
343 | 370 | transInterfaceParams,
|
@@ -809,7 +836,7 @@ case TypeKind::Id:
|
809 | 836 | }
|
810 | 837 |
|
811 | 838 | // Transform result type.
|
812 |
| - auto resultTy = doIt(function->getResult(), pos); |
| 839 | + Type resultTy = doIt(function->getResult(), pos); |
813 | 840 | if (!resultTy)
|
814 | 841 | return Type();
|
815 | 842 |
|
@@ -876,8 +903,45 @@ case TypeKind::Id:
|
876 | 903 | return GenericFunctionType::get(
|
877 | 904 | genericSig, substParams, resultTy, extInfo);
|
878 | 905 | }
|
| 906 | + |
| 907 | + if (isUnchanged) { |
| 908 | + return t; |
| 909 | + } |
879 | 910 |
|
880 |
| - if (isUnchanged) return t; |
| 911 | + // Substitution may have replaced parameter or return types that had |
| 912 | + // lifetime dependencies with Escapable types, which render those |
| 913 | + // dependencies inactive. |
| 914 | + if (extInfo && !extInfo->getLifetimeDependencies().empty()) { |
| 915 | + SmallVector<LifetimeDependenceInfo, 2> substDependenceInfos; |
| 916 | + bool didRemoveLifetimeDependencies |
| 917 | + = filterEscapableLifetimeDependencies(GenericSignature(), |
| 918 | + extInfo->getLifetimeDependencies(), |
| 919 | + substDependenceInfos, |
| 920 | + [&](unsigned targetIndex) { |
| 921 | + // Traverse potentially-curried function types. |
| 922 | + ArrayRef<AnyFunctionType::Param> params = substParams; |
| 923 | + auto result = resultTy; |
| 924 | + while (targetIndex >= params.size()) { |
| 925 | + if (auto curriedTy = result->getAs<AnyFunctionType>()) { |
| 926 | + targetIndex -= params.size(); |
| 927 | + params = curriedTy->getParams(); |
| 928 | + result = curriedTy->getResult(); |
| 929 | + continue; |
| 930 | + } else { |
| 931 | + // The last lifetime dependency targets the result at the end |
| 932 | + // of the curried chain. |
| 933 | + ASSERT(targetIndex == params.size() |
| 934 | + && "invalid lifetime dependence target"); |
| 935 | + return result; |
| 936 | + } |
| 937 | + } |
| 938 | + return params[targetIndex].getParameterType(); |
| 939 | + }); |
| 940 | + |
| 941 | + if (didRemoveLifetimeDependencies) { |
| 942 | + extInfo = extInfo->withLifetimeDependencies(substDependenceInfos); |
| 943 | + } |
| 944 | + } |
881 | 945 |
|
882 | 946 | return FunctionType::get(substParams, resultTy, extInfo);
|
883 | 947 | }
|
|
0 commit comments