mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
When a method is called with fewer than two parameter lists,
transform it into a fully-applied call by wrapping it in a
closure.
Eg,
Foo.bar => { self in { args... self.bar(args...) } }
foo.bar => { self in { args... self.bar(args...) } }(self)
super.bar => { args... in super.bar(args...) }
With this change, SILGen only ever sees fully-applied calls,
which will allow ripping out some code.
This new way of doing curry thunks fixes a long-standing bug
where unbound references to protocol methods did not work.
This is because such a reference must open the existential
*inside* the closure, after 'self' has been applied, whereas
the old SILGen implementation of curry thunks really wanted
the type of the method reference to match the opened type of
the method.
A follow-up cleanup will remove the SILGen curry thunk
implementation.
Fixes rdar://21289579 and https://bugs.swift.org/browse/SR-75.
119 lines
2.5 KiB
Swift
119 lines
2.5 KiB
Swift
// RUN: %target-swift-emit-silgen -parse-as-library -module-name Swift -parse-stdlib %s
|
|
|
|
// This test checks specific codegen related to converting curry thunks to
|
|
// canonical representations when we are emitting guaranteed normal
|
|
// arguments. Eventually it will be merged into the normal SILGen tests.
|
|
|
|
//////////////////
|
|
// Declarations //
|
|
//////////////////
|
|
|
|
precedencegroup AssignmentPrecedence {
|
|
assignment: true
|
|
}
|
|
|
|
enum Optional<T> {
|
|
case none
|
|
case some(T)
|
|
}
|
|
|
|
func _diagnoseUnexpectedNilOptional(_filenameStart: Builtin.RawPointer,
|
|
_filenameLength: Builtin.Word,
|
|
_filenameIsASCII: Builtin.Int1,
|
|
_line: Builtin.Word) {
|
|
// This would usually contain an assert, but we don't need one since we are
|
|
// just emitting SILGen.
|
|
}
|
|
|
|
class Klass {
|
|
init() {}
|
|
}
|
|
|
|
typealias AnyObject = Builtin.AnyObject
|
|
|
|
protocol ProtocolInitNoArg {
|
|
init()
|
|
}
|
|
|
|
protocol ClassProtocolInitNoArg : class {
|
|
init()
|
|
}
|
|
|
|
protocol ProtocolInitAddressOnly {
|
|
associatedtype SubType : ProtocolInitNoArg
|
|
|
|
init(t: SubType)
|
|
init(t2: AddrOnlyStructInitGeneric<Klass>)
|
|
init(t3: AddrOnlyStructInitGeneric<SubType>)
|
|
}
|
|
|
|
protocol ProtocolInitClassProtocol {
|
|
associatedtype SubType : ClassProtocolInitNoArg
|
|
|
|
init(t: SubType)
|
|
}
|
|
|
|
protocol ProtocolInitLoadable {
|
|
init(t: Klass)
|
|
}
|
|
|
|
protocol ClassProtocolInitAddressOnly : class {
|
|
associatedtype SubType : ProtocolInitNoArg
|
|
|
|
init(t: SubType)
|
|
}
|
|
|
|
protocol ClassProtocolInitClassProtocol : class {
|
|
associatedtype SubType : ClassProtocolInitNoArg
|
|
|
|
init(t: SubType)
|
|
}
|
|
|
|
protocol ClassProtocolInitLoadable : class {
|
|
init(t: Klass)
|
|
}
|
|
|
|
class LoadableClassInitLoadable {
|
|
init(_ k: Klass) {}
|
|
}
|
|
|
|
struct LoadableStructInitLoadable {
|
|
var k: Klass
|
|
|
|
init(_ newK: Klass) {
|
|
k = newK
|
|
}
|
|
}
|
|
|
|
struct AddrOnlyStructInitGeneric<T> {
|
|
var k: T
|
|
|
|
init(_ newK: T) {
|
|
k = newK
|
|
}
|
|
}
|
|
|
|
///////////
|
|
// Tests //
|
|
///////////
|
|
|
|
// There used to be FileCheck tests here. Now that curry thunks are built
|
|
// in CSApply, there's no point writing them out in great detail again.
|
|
// Let's just make sure we don't hit any assertions or SIL verifier
|
|
// failures.
|
|
|
|
func testAddrOnlyStructInitGenericConcrete() {
|
|
let x = AddrOnlyStructInitGeneric<Klass>.init
|
|
let y = x(Klass())
|
|
}
|
|
|
|
func testAddrOnlyStructInitGenericAddrOnly<T : ProtocolInitAddressOnly>(t: T) {
|
|
let x = AddrOnlyStructInitGeneric<T.SubType>.init
|
|
let y = x(T.SubType())
|
|
}
|
|
|
|
func testGenericInitClass<T : ProtocolInitLoadable>(t: T) {
|
|
let x = T.init
|
|
let y = x(Klass())
|
|
}
|