The following code:
enum StringSource {
case string(String)
case staticString(StaticString)
}
struct Name {
var first: StringSource?
var last: StringSource?
}
func test(body: () -> Name) {
body()
}
Generates the following assembly:
output.test(body: () -> output.Name) -> ():
// ...
call (outlined destroy of output.StringSource?)
// ...
call (outlined destroy of output.StringSource?)
outlined destroy of output.StringSource?:
push rbx
mov rbx, rdi
lea rdi, [rip + (demangling cache variable for type metadata for output.StringSource?)]
call __swift_instantiateConcreteTypeFromMangledName
mov rcx, qword ptr [rax - 8]
mov rdi, rbx
mov rsi, rax
call qword ptr [rcx + 8]
mov rax, rbx
pop rbx
ret
I'm guessing this has something to do with the compiler's rules around when to inline and when to specialize, but it seems like an unnecessary penalty to me to have to make this destruction generic.
Is this a bug, a potential unimplemented optimization, or necessary for some other reason I'm missing?
Also, is there a way I can force Swift to use a specialized implementation?
EDIT:
This also happens with other type operations, like copies:
func test(name: Name) -> Name {
name
}
output.test(name: output.Name) -> output.Name:
// ...
call (outlined init with copy of output.StringSource?)
// ...
call (outlined init with copy of output.StringSource?)
// ...
outlined init with copy of output.StringSource?:
// ...
call __swift_instantiateConcreteTypeFromMangledName
// ...