@@ -1378,6 +1378,10 @@ class DestructureResults {
13781378 return ;
13791379 }
13801380
1381+ // Skip yields, they should've already processed elsewhere
1382+ if (isa<YieldResultType>(substType))
1383+ return ;
1384+
13811385 auto &substResultTLForConvention = TC.getTypeLowering (
13821386 origType, substType, TypeExpansionContext::minimal ());
13831387 auto &substResultTL = TC.getTypeLowering (origType, substType,
@@ -2221,23 +2225,22 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
22212225 " iterating over loweredCaptures.getCaptures()." );
22222226}
22232227
2224- static AccessorDecl *
2225- getAsCoroutineAccessor (std::optional<SILDeclRef> constant) {
2228+ static FuncDecl *getAsCoroutine (std::optional<SILDeclRef> constant) {
22262229 if (!constant || !constant->hasDecl ())
22272230 return nullptr ;;
22282231
2229- auto accessor = dyn_cast<AccessorDecl >(constant->getDecl ());
2230- if (!accessor || !accessor ->isCoroutine ())
2232+ auto fd = dyn_cast<FuncDecl >(constant->getDecl ());
2233+ if (!fd || !fd ->isCoroutine ())
22312234 return nullptr ;
22322235
2233- return accessor ;
2236+ return fd ;
22342237}
22352238
22362239static void destructureYieldsForReadAccessor (TypeConverter &TC,
2237- TypeExpansionContext expansion,
2238- AbstractionPattern origType,
2239- CanType valueType,
2240- SmallVectorImpl<SILYieldInfo> &yields){
2240+ TypeExpansionContext expansion,
2241+ AbstractionPattern origType,
2242+ CanType valueType,
2243+ SmallVectorImpl<SILYieldInfo> &yields){
22412244 // Recursively destructure tuples.
22422245 if (origType.isTuple ()) {
22432246 auto valueTupleType = cast<TupleType>(valueType);
@@ -2269,25 +2272,19 @@ static void destructureYieldsForReadAccessor(TypeConverter &TC,
22692272
22702273static void destructureYieldsForCoroutine (TypeConverter &TC,
22712274 TypeExpansionContext expansion,
2272- std::optional<SILDeclRef> constant,
22732275 AbstractionPattern origType,
22742276 CanType canValueType,
2275- SmallVectorImpl<SILYieldInfo> &yields,
2276- SILCoroutineKind &coroutineKind) {
2277- auto accessor = getAsCoroutineAccessor (constant);
2278- if (!accessor)
2279- return ;
2280-
2277+ bool isInOutYield,
2278+ SmallVectorImpl<SILYieldInfo> &yields) {
22812279 // 'modify' yields an inout of the target type.
2282- if (isYieldingMutableAccessor (accessor-> getAccessorKind ()) ) {
2280+ if (isInOutYield ) {
22832281 auto loweredValueTy =
22842282 TC.getLoweredType (origType, canValueType, expansion);
22852283 yields.push_back (SILYieldInfo (loweredValueTy.getASTType (),
22862284 ParameterConvention::Indirect_Inout));
22872285 } else {
22882286 // 'read' yields a borrowed value of the target type, destructuring
22892287 // tuples as necessary.
2290- assert (isYieldingImmutableAccessor (accessor->getAccessorKind ()));
22912288 destructureYieldsForReadAccessor (TC, expansion, origType, canValueType,
22922289 yields);
22932290 }
@@ -2377,35 +2374,42 @@ static CanSILFunctionType getSILFunctionType(
23772374
23782375 bool hasSendingResult = substFnInterfaceType->getExtInfo ().hasSendingResult ();
23792376
2380- // Get the yield type for an accessor coroutine.
2377+ // Get the yield type for coroutine.
23812378 SILCoroutineKind coroutineKind = SILCoroutineKind::None;
23822379 AbstractionPattern coroutineOrigYieldType = AbstractionPattern::getInvalid ();
23832380 CanType coroutineSubstYieldType;
23842381
2385- if (auto accessor = getAsCoroutineAccessor (constant)) {
2386- auto origAccessor = cast<AccessorDecl>(origConstant->getDecl ());
2387- coroutineKind =
2382+ bool isInOutYield = false ;
2383+ if (auto fd = getAsCoroutine (constant)) {
2384+ auto origFd = cast<FuncDecl>(origConstant->getDecl ());
2385+ if (auto accessor = dyn_cast<AccessorDecl>(origFd)) {
2386+ coroutineKind =
23882387 requiresFeatureCoroutineAccessors (accessor->getAccessorKind ())
2389- ? SILCoroutineKind::YieldOnce2
2390- : SILCoroutineKind::YieldOnce;
2391-
2388+ ? SILCoroutineKind::YieldOnce2
2389+ : SILCoroutineKind::YieldOnce;
2390+ } else {
2391+ // FIXME: Decide we'd directly go to YieldOnce2 for non-accessor coroutines
2392+ coroutineKind = SILCoroutineKind::YieldOnce;
2393+ }
2394+
23922395 // Coroutine accessors are always native, so fetch the native
23932396 // abstraction pattern.
2394- auto origStorage = origAccessor->getStorage ();
2395- coroutineOrigYieldType = TC.getAbstractionPattern (origStorage,
2396- /* nonobjc*/ true )
2397- .getReferenceStorageReferentType ();
2398-
2399- auto storage = accessor->getStorage ();
2400- auto valueType = storage->getValueInterfaceType ();
2397+ auto sig = origFd->getGenericSignatureOfContext ()
2398+ .getCanonicalSignature ();
2399+ auto origYieldType = origFd->getYieldsInterfaceType ()->castTo <YieldResultType>();
2400+ auto reducedYieldType = sig.getReducedType (origYieldType->getResultType ());
2401+ coroutineOrigYieldType = AbstractionPattern (sig, reducedYieldType);
24012402
2403+ auto yieldType = fd->getYieldsInterfaceType ()->castTo <YieldResultType>();
2404+ auto valueType = yieldType->getResultType ();
2405+ isInOutYield = yieldType->isInOut ();
24022406 if (reqtSubs) {
24032407 valueType = valueType.subst (*reqtSubs);
24042408 coroutineSubstYieldType = valueType->getReducedType (
24052409 genericSig);
24062410 } else {
24072411 coroutineSubstYieldType = valueType->getReducedType (
2408- accessor ->getGenericSignature ());
2412+ fd ->getGenericSignature ());
24092413 }
24102414 }
24112415
@@ -2430,7 +2434,8 @@ static CanSILFunctionType getSILFunctionType(
24302434 // for class override thunks. This is required to make the yields
24312435 // match in abstraction to the base method's yields, which is necessary
24322436 // to make the extracted continuation-function signatures match.
2433- if (constant != origConstant && getAsCoroutineAccessor (constant))
2437+ if (constant != origConstant &&
2438+ coroutineKind != SILCoroutineKind::None)
24342439 return true ;
24352440
24362441 // We don't currently use substituted function types for generic function
@@ -2546,10 +2551,12 @@ static CanSILFunctionType getSILFunctionType(
25462551
25472552 // Destructure the coroutine yields.
25482553 SmallVector<SILYieldInfo, 8 > yields;
2549- destructureYieldsForCoroutine (TC, expansionContext, constant,
2550- coroutineOrigYieldType, coroutineSubstYieldType,
2551- yields, coroutineKind);
2552-
2554+ if (coroutineKind != SILCoroutineKind::None) {
2555+ destructureYieldsForCoroutine (TC, expansionContext,
2556+ coroutineOrigYieldType, coroutineSubstYieldType,
2557+ isInOutYield, yields);
2558+ }
2559+
25532560 // Destructure the result tuple type.
25542561 SmallVector<SILResultInfo, 8 > results;
25552562 {
@@ -4724,6 +4731,8 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant,
47244731 extInfo = extInfo.withThrows (true , innerExtInfo.getThrownError ());
47254732 if (innerExtInfo.isAsync ())
47264733 extInfo = extInfo.withAsync (true );
4734+ if (innerExtInfo.isCoroutine ())
4735+ extInfo = extInfo.withCoroutine (true );
47274736
47284737 // Distributed thunks are always `async throws`
47294738 if (constant.isDistributedThunk ()) {
0 commit comments