mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Yield types are not represented in the AST FunctionType, so when we compute the lowered type of a witness thunk for a 'modify' or 'read' coroutine, we have to compute the yield type from scratch. We do this by applying the witness substitutions computed by Sema to the storage type, and then canonicalizing the resulting substituted type with respect to the storage's own generic signature. However, the right hand sides of the witness substitutions are written with respect to the conformance context, which might be a subclass of the class that the storage is originally defined in. By not using the generic signature of this subclass, we could miss associated types of generic parameters of the base class which were made concrete in the subclass using a 'where' clause. Instead, let's pass down the generic signature of the witness thunk, ensuring we always compute the correct canonical type. Fixes rdar://problem/77737914.
27 lines
1.5 KiB
Swift
27 lines
1.5 KiB
Swift
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
|
|
|
|
public protocol P {
|
|
associatedtype A
|
|
}
|
|
|
|
public class Base<T: P> {
|
|
public var foo: T.A?
|
|
}
|
|
|
|
public struct S {}
|
|
|
|
public protocol Q {
|
|
var foo: S? {set get}
|
|
}
|
|
|
|
public class Derived<T: P> : Base<T>, Q where T.A == S {}
|
|
|
|
// 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> {
|
|
// 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>) -> () {
|
|
// 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>> {
|
|
|
|
// CHECK-LABEL: sil_witness_table [serialized] <T where T : P, T.A == S> Derived<T>: Q module main {
|
|
// CHECK-NEXT: method #Q.foo!getter: <Self where Self : Q> (Self) -> () -> S? : @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvgTW
|
|
// CHECK-NEXT: method #Q.foo!setter: <Self where Self : Q> (inout Self) -> (S?) -> () : @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvsTW
|
|
// CHECK-NEXT: method #Q.foo!modify: <Self where Self : Q> (inout Self) -> () -> () : @$s4main7DerivedCyxGAA1QA2aEP3fooAA1SVSgvMTW
|
|
// CHECK-NEXT: } |