Skip to content

Commit f1df707

Browse files
authored
Merge pull request #37620 from slavapestov/coroutine-witness-from-base-class
SIL: Use correct generic signature when computing yield types for witness thunks
2 parents 346500f + a5fc7ea commit f1df707

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,7 @@ static void destructureYieldsForCoroutine(TypeConverter &TC,
19881988
Optional<SILDeclRef> origConstant,
19891989
Optional<SILDeclRef> constant,
19901990
Optional<SubstitutionMap> reqtSubs,
1991+
Optional<GenericSignature> genericSig,
19911992
SmallVectorImpl<SILYieldInfo> &yields,
19921993
SILCoroutineKind &coroutineKind,
19931994
SubstFunctionTypeCollector &subst) {
@@ -2012,12 +2013,14 @@ static void destructureYieldsForCoroutine(TypeConverter &TC,
20122013

20132014
auto storage = accessor->getStorage();
20142015
auto valueType = storage->getValueInterfaceType();
2016+
20152017
if (reqtSubs) {
20162018
valueType = valueType.subst(*reqtSubs);
20172019
}
20182020

2019-
auto canValueType = valueType->getCanonicalType(
2020-
accessor->getGenericSignature());
2021+
auto canValueType = (genericSig
2022+
? valueType->getCanonicalType(*genericSig)
2023+
: valueType->getCanonicalType());
20212024

20222025
// 'modify' yields an inout of the target type.
20232026
if (accessor->getAccessorKind() == AccessorKind::Modify) {
@@ -2178,7 +2181,8 @@ static CanSILFunctionType getSILFunctionType(
21782181
SILCoroutineKind coroutineKind = SILCoroutineKind::None;
21792182
SmallVector<SILYieldInfo, 8> yields;
21802183
destructureYieldsForCoroutine(TC, expansionContext, origConstant, constant,
2181-
reqtSubs, yields, coroutineKind, subst);
2184+
reqtSubs, genericSig, yields, coroutineKind,
2185+
subst);
21822186

21832187
// Destructure the result tuple type.
21842188
SmallVector<SILResultInfo, 8> results;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
3+
public protocol P {
4+
associatedtype A
5+
}
6+
7+
public class Base<T: P> {
8+
public var foo: T.A?
9+
}
10+
11+
public struct S {}
12+
13+
public protocol Q {
14+
var foo: S? {set get}
15+
}
16+
17+
public class Derived<T: P> : Base<T>, Q where T.A == S {}
18+
19+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvgTW : $@convention(witness_method: Q) <τ_0_0 where τ_0_0 : P, τ_0_0.A == S> (@in_guaranteed Derived<τ_0_0>) -> Optional<S> {
20+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvsTW : $@convention(witness_method: Q) <τ_0_0 where τ_0_0 : P, τ_0_0.A == S> (Optional<S>, @inout Derived<τ_0_0>) -> () {
21+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvMTW : $@yield_once @convention(witness_method: Q) <τ_0_0 where τ_0_0 : P, τ_0_0.A == S> @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Optional<S> for <Derived<τ_0_0>> {
22+
23+
// CHECK-LABEL: sil_witness_table [serialized] <T where T : P, T.A == S> Derived<T>: Q module main {
24+
// CHECK-NEXT: method #Q.foo!getter: <Self where Self : Q> (Self) -> () -> S? : @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvgTW
25+
// CHECK-NEXT: method #Q.foo!setter: <Self where Self : Q> (inout Self) -> (S?) -> () : @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvsTW
26+
// CHECK-NEXT: method #Q.foo!modify: <Self where Self : Q> (inout Self) -> () -> () : @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvMTW
27+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)