@@ -1417,6 +1417,10 @@ class DestructureResults {
14171417 return ;
14181418 }
14191419
1420+ // Skip yields, they should've already processed elsewhere
1421+ if (isa<YieldResultType>(substType))
1422+ return ;
1423+
14201424 auto &substResultTLForConvention = TC.getTypeLowering (
14211425 origType, substType, TypeExpansionContext::minimal ());
14221426 auto &substResultTL = TC.getTypeLowering (origType, substType,
@@ -2317,23 +2321,22 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
23172321 " iterating over loweredCaptures.getCaptures()." );
23182322}
23192323
2320- static AccessorDecl *
2321- getAsCoroutineAccessor (std::optional<SILDeclRef> constant) {
2324+ static FuncDecl *getAsCoroutine (std::optional<SILDeclRef> constant) {
23222325 if (!constant || !constant->hasDecl ())
23232326 return nullptr ;;
23242327
2325- auto accessor = dyn_cast<AccessorDecl >(constant->getDecl ());
2326- if (!accessor || !accessor ->isCoroutine ())
2328+ auto fd = dyn_cast<FuncDecl >(constant->getDecl ());
2329+ if (!fd || !fd ->isCoroutine ())
23272330 return nullptr ;
23282331
2329- return accessor ;
2332+ return fd ;
23302333}
23312334
23322335static void destructureYieldsForReadAccessor (TypeConverter &TC,
2333- TypeExpansionContext expansion,
2334- AbstractionPattern origType,
2335- CanType valueType,
2336- SmallVectorImpl<SILYieldInfo> &yields){
2336+ TypeExpansionContext expansion,
2337+ AbstractionPattern origType,
2338+ CanType valueType,
2339+ SmallVectorImpl<SILYieldInfo> &yields){
23372340 // Recursively destructure tuples.
23382341 if (origType.isTuple ()) {
23392342 auto valueTupleType = cast<TupleType>(valueType);
@@ -2365,25 +2368,19 @@ static void destructureYieldsForReadAccessor(TypeConverter &TC,
23652368
23662369static void destructureYieldsForCoroutine (TypeConverter &TC,
23672370 TypeExpansionContext expansion,
2368- std::optional<SILDeclRef> constant,
23692371 AbstractionPattern origType,
23702372 CanType canValueType,
2371- SmallVectorImpl<SILYieldInfo> &yields,
2372- SILCoroutineKind &coroutineKind) {
2373- auto accessor = getAsCoroutineAccessor (constant);
2374- if (!accessor)
2375- return ;
2376-
2373+ bool isInOutYield,
2374+ SmallVectorImpl<SILYieldInfo> &yields) {
23772375 // 'modify' yields an inout of the target type.
2378- if (isYieldingMutableAccessor (accessor-> getAccessorKind ()) ) {
2376+ if (isInOutYield ) {
23792377 auto loweredValueTy =
23802378 TC.getLoweredType (origType, canValueType, expansion);
23812379 yields.push_back (SILYieldInfo (loweredValueTy.getASTType (),
23822380 ParameterConvention::Indirect_Inout));
23832381 } else {
23842382 // 'read' yields a borrowed value of the target type, destructuring
23852383 // tuples as necessary.
2386- assert (isYieldingImmutableAccessor (accessor->getAccessorKind ()));
23872384 destructureYieldsForReadAccessor (TC, expansion, origType, canValueType,
23882385 yields);
23892386 }
@@ -2511,37 +2508,44 @@ static CanSILFunctionType getSILFunctionType(
25112508
25122509 bool hasSendingResult = substFnInterfaceType->getExtInfo ().hasSendingResult ();
25132510
2514- // Get the yield type for an accessor coroutine.
2511+ // Get the yield type for coroutine.
25152512 SILCoroutineKind coroutineKind = SILCoroutineKind::None;
25162513 AbstractionPattern coroutineOrigYieldType = AbstractionPattern::getInvalid ();
25172514 CanType coroutineSubstYieldType;
25182515
2519- if (auto accessor = getAsCoroutineAccessor (constant)) {
2520- auto origAccessor = cast<AccessorDecl>(origConstant->getDecl ());
2521- auto &ctx = origAccessor->getASTContext ();
2522- coroutineKind =
2516+ bool isInOutYield = false ;
2517+ if (auto fd = getAsCoroutine (constant)) {
2518+ auto origFd = cast<FuncDecl>(origConstant->getDecl ());
2519+ auto &ctx = origFd->getASTContext ();
2520+ if (auto accessor = dyn_cast<AccessorDecl>(origFd)) {
2521+ coroutineKind =
25232522 (requiresFeatureCoroutineAccessors (accessor->getAccessorKind ()) &&
25242523 ctx.SILOpts .CoroutineAccessorsUseYieldOnce2 )
2525- ? SILCoroutineKind::YieldOnce2
2526- : SILCoroutineKind::YieldOnce;
2527-
2524+ ? SILCoroutineKind::YieldOnce2
2525+ : SILCoroutineKind::YieldOnce;
2526+ } else {
2527+ // FIXME: Decide we'd directly go to YieldOnce2 for non-accessor coroutines
2528+ coroutineKind = SILCoroutineKind::YieldOnce;
2529+ }
2530+
25282531 // Coroutine accessors are always native, so fetch the native
25292532 // abstraction pattern.
2530- auto origStorage = origAccessor->getStorage ();
2531- coroutineOrigYieldType = TC.getAbstractionPattern (origStorage,
2532- /* nonobjc*/ true )
2533- .getReferenceStorageReferentType ();
2534-
2535- auto storage = accessor->getStorage ();
2536- auto valueType = storage->getValueInterfaceType ();
2533+ auto sig = origFd->getGenericSignatureOfContext ()
2534+ .getCanonicalSignature ();
2535+ auto origYieldType = origFd->getYieldsInterfaceType ()->castTo <YieldResultType>();
2536+ auto reducedYieldType = sig.getReducedType (origYieldType->getResultType ());
2537+ coroutineOrigYieldType = AbstractionPattern (sig, reducedYieldType);
25372538
2539+ auto yieldType = fd->getYieldsInterfaceType ()->castTo <YieldResultType>();
2540+ auto valueType = yieldType->getResultType ();
2541+ isInOutYield = yieldType->isInOut ();
25382542 if (reqtSubs) {
25392543 valueType = valueType.subst (*reqtSubs);
25402544 coroutineSubstYieldType = valueType->getReducedType (
25412545 genericSig);
25422546 } else {
25432547 coroutineSubstYieldType = valueType->getReducedType (
2544- accessor ->getGenericSignature ());
2548+ fd ->getGenericSignature ());
25452549 }
25462550 }
25472551
@@ -2566,7 +2570,8 @@ static CanSILFunctionType getSILFunctionType(
25662570 // for class override thunks. This is required to make the yields
25672571 // match in abstraction to the base method's yields, which is necessary
25682572 // to make the extracted continuation-function signatures match.
2569- if (constant != origConstant && getAsCoroutineAccessor (constant))
2573+ if (constant != origConstant &&
2574+ coroutineKind != SILCoroutineKind::None)
25702575 return true ;
25712576
25722577 // We don't currently use substituted function types for generic function
@@ -2670,10 +2675,12 @@ static CanSILFunctionType getSILFunctionType(
26702675
26712676 // Destructure the coroutine yields.
26722677 SmallVector<SILYieldInfo, 8 > yields;
2673- destructureYieldsForCoroutine (TC, expansionContext, constant,
2674- coroutineOrigYieldType, coroutineSubstYieldType,
2675- yields, coroutineKind);
2676-
2678+ if (coroutineKind != SILCoroutineKind::None) {
2679+ destructureYieldsForCoroutine (TC, expansionContext,
2680+ coroutineOrigYieldType, coroutineSubstYieldType,
2681+ isInOutYield, yields);
2682+ }
2683+
26772684 // Destructure the result tuple type.
26782685 SmallVector<SILResultInfo, 8 > results;
26792686 {
@@ -4977,6 +4984,8 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant,
49774984 extInfo = extInfo.withThrows (true , innerExtInfo.getThrownError ());
49784985 if (innerExtInfo.isAsync ())
49794986 extInfo = extInfo.withAsync (true );
4987+ if (innerExtInfo.isCoroutine ())
4988+ extInfo = extInfo.withCoroutine (true );
49804989
49814990 // Distributed thunks are always `async throws`
49824991 if (constant.isDistributedThunk ()) {
0 commit comments