@@ -497,6 +497,10 @@ namespace {
497
497
RValue
498
498
emitFunctionCvtFromExecutionCallerToGlobalActor (FunctionConversionExpr *E,
499
499
SGFContext C);
500
+
501
+ RValue emitFunctionCvtForNonisolatedNonsendingClosureExpr (
502
+ FunctionConversionExpr *E, SGFContext C);
503
+
500
504
RValue visitActorIsolationErasureExpr (ActorIsolationErasureExpr *E,
501
505
SGFContext C);
502
506
RValue visitExtractFunctionIsolationExpr (ExtractFunctionIsolationExpr *E,
@@ -2031,6 +2035,44 @@ RValueEmitter::emitFunctionCvtToExecutionCaller(FunctionConversionExpr *e,
2031
2035
return RValue (SGF, e, destType, result);
2032
2036
}
2033
2037
2038
+ RValue RValueEmitter::emitFunctionCvtForNonisolatedNonsendingClosureExpr (
2039
+ FunctionConversionExpr *E, SGFContext C) {
2040
+ // The specific AST pattern for this looks as follows:
2041
+ //
2042
+ // (function_conversion_expr type="nonisolated(nonsending) () async -> Void"
2043
+ // (closure_expr type="() async -> ()" isolated_to_caller_isolation))
2044
+ CanAnyFunctionType destType =
2045
+ cast<FunctionType>(E->getType ()->getCanonicalType ());
2046
+ auto subExpr = E->getSubExpr ()->getSemanticsProvidingExpr ();
2047
+
2048
+ // If we do not have a closure or if that closure is not caller isolation
2049
+ // inheriting, bail.
2050
+ auto *closureExpr = dyn_cast<ClosureExpr>(subExpr);
2051
+ if (!closureExpr ||
2052
+ !closureExpr->getActorIsolation ().isCallerIsolationInheriting ())
2053
+ return RValue ();
2054
+
2055
+ // Then grab our closure type... make sure it is non isolated and then make
2056
+ // sure it is the same as our destType but with nonisolated.
2057
+ CanAnyFunctionType closureType =
2058
+ cast<FunctionType>(closureExpr->getType ()->getCanonicalType ());
2059
+ if (!closureType->getIsolation ().isNonIsolated () ||
2060
+ closureType !=
2061
+ destType->withIsolation (FunctionTypeIsolation::forNonIsolated ())
2062
+ ->getCanonicalType ())
2063
+ return RValue ();
2064
+
2065
+ // NOTE: This is a partial inline of getClosureTypeInfo. We do this so we have
2066
+ // more control and make this change less viral in the compiler for 6.2.
2067
+ auto newExtInfo = closureType->getExtInfo ().withIsolation (
2068
+ FunctionTypeIsolation::forNonIsolatedCaller ());
2069
+ closureType = closureType.withExtInfo (newExtInfo);
2070
+ auto info = SGF.getFunctionTypeInfo (closureType);
2071
+
2072
+ auto closure = emitClosureReference (closureExpr, info);
2073
+ return RValue (SGF, closureExpr, destType, closure);
2074
+ }
2075
+
2034
2076
RValue RValueEmitter::emitFunctionCvtFromExecutionCallerToGlobalActor (
2035
2077
FunctionConversionExpr *e, SGFContext C) {
2036
2078
// We are pattern matching a conversion sequence like the following:
@@ -2142,6 +2184,28 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
2142
2184
// TODO: Move this up when we can emit closures directly with C calling
2143
2185
// convention.
2144
2186
auto subExpr = e->getSubExpr ()->getSemanticsProvidingExpr ();
2187
+
2188
+ // Before we go any further into emitting the convert function expr, see if
2189
+ // our SubExpr is a ClosureExpr with the exact same type as our
2190
+ // FunctionConversionExpr except with the FunctionConversionExpr adding
2191
+ // nonisolated(nonsending). Then see if the ClosureExpr itself (even though it
2192
+ // is not nonisolated(nonsending) typed is considered to have
2193
+ // nonisolated(nonsending) isolation. In such a case, emit the closure
2194
+ // directly. We are going to handle it especially in closure emission to work
2195
+ // around the missing information in the type.
2196
+ //
2197
+ // DISCUSSION: We need to do this here since in the Expression TypeChecker we
2198
+ // do not have access to capture information when we would normally want to
2199
+ // mark the closure type as being nonisolated(nonsending). As a result, we
2200
+ // cannot know if the nonisolated(nonsending) should be overridden by for
2201
+ // example an actor that is captured by the closure. So to work around this in
2202
+ // Sema, we still mark the ClosureExpr as having the appropriate isolation
2203
+ // even though its type does not have it... and then we work around this here
2204
+ // and also in getClosureTypeInfo.
2205
+ if (destType->getIsolation ().isNonIsolatedCaller ())
2206
+ if (auto rv = emitFunctionCvtForNonisolatedNonsendingClosureExpr (e, C))
2207
+ return rv;
2208
+
2145
2209
// Look through `as` type ascriptions that don't induce bridging too.
2146
2210
while (auto subCoerce = dyn_cast<CoerceExpr>(subExpr)) {
2147
2211
// Coercions that introduce bridging aren't simple type ascriptions.
0 commit comments