mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
50 lines
1.3 KiB
Swift
50 lines
1.3 KiB
Swift
// RUN: %target-swiftc_driver %s -g %import-libdispatch -o %t
|
|
// RUN: %target-codesign %t
|
|
// RUN: %target-run %t
|
|
// REQUIRES: libdispatch
|
|
// REQUIRES: executable_test
|
|
// UNSUPPORTED: threading_none
|
|
|
|
import Dispatch
|
|
|
|
protocol P {
|
|
associatedtype Unused
|
|
}
|
|
struct A<T> : P {
|
|
// We never actually read this associated type, but its presence in the
|
|
// wtable should force it to be instantiated rather than shared for
|
|
// all specializations of A.
|
|
typealias Unused = A<A<T>>
|
|
}
|
|
|
|
protocol Q {
|
|
associatedtype Assoc: P
|
|
|
|
func foo()
|
|
}
|
|
struct B<T: P> : Q {
|
|
// Both the metadata and the wtable for this associated type require
|
|
// runtime instantiation and must be fetched lazily.
|
|
typealias Assoc = A<T>
|
|
|
|
func foo() {}
|
|
}
|
|
|
|
// It's possible that the optimizer might someday be able to recognize
|
|
// that this is a no-op.
|
|
func rundown<T: Q>(value: T, count: Int) {
|
|
guard count > 0 else { return }
|
|
|
|
value.foo()
|
|
|
|
// Assuming that T is B<U> for some U, this constructs B<A<U>>,
|
|
// which will be T in the recursive call; i.e. we should have a
|
|
// different metadata/wtable pair each time. In order to construct
|
|
// that, we have to read the associated metadata and wtable for T.Assoc.
|
|
rundown(value: B<T.Assoc>(), count: count - 1)
|
|
}
|
|
|
|
DispatchQueue.concurrentPerform(iterations: 5) { n in
|
|
rundown(value: B<A<()>>(), count: 1000)
|
|
}
|