@@ -497,6 +497,10 @@ namespace {
497497 RValue
498498 emitFunctionCvtFromExecutionCallerToGlobalActor (FunctionConversionExpr *E,
499499 SGFContext C);
500+
501+ RValue emitFunctionCvtForNonisolatedNonsendingClosureExpr (
502+ FunctionConversionExpr *E, SGFContext C);
503+
500504 RValue visitActorIsolationErasureExpr (ActorIsolationErasureExpr *E,
501505 SGFContext C);
502506 RValue visitExtractFunctionIsolationExpr (ExtractFunctionIsolationExpr *E,
@@ -2031,6 +2035,44 @@ RValueEmitter::emitFunctionCvtToExecutionCaller(FunctionConversionExpr *e,
20312035 return RValue (SGF, e, destType, result);
20322036}
20332037
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+
20342076RValue RValueEmitter::emitFunctionCvtFromExecutionCallerToGlobalActor (
20352077 FunctionConversionExpr *e, SGFContext C) {
20362078 // We are pattern matching a conversion sequence like the following:
@@ -2142,6 +2184,28 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
21422184 // TODO: Move this up when we can emit closures directly with C calling
21432185 // convention.
21442186 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+
21452209 // Look through `as` type ascriptions that don't induce bridging too.
21462210 while (auto subCoerce = dyn_cast<CoerceExpr>(subExpr)) {
21472211 // Coercions that introduce bridging aren't simple type ascriptions.
0 commit comments