I'm processing @kavon's feedback in https://github.com/swiftlang/swift/pull/84789.
I'm trying to lower CollectionUpcastConversionExpr::ConversionPair as a closure with correct abstraction pattern. There is SILGenFunction::emitConvertedRValue() that can handle ClosureExpr, but cannot handle ConversionPair. My first attempt was to convert CollectionUpcastConversionExpr::ConversionPair into a short-lived ClosureExpr that exists only to be fed to emitConvertedRValue() and is detached from the rest of the AST.
Now based on @kavon's feedback, I'm trying to avoid AST generation in SILGen.
Options I'm considering:
- Use
ClosureExpras a representation ofKeyConversionandValueConversion- it was easy to adapt previous solution into this one, but I'm concerned that I don't fully understand the role ofOpaqueValueExpr-based abstractions. - Create override of
SILGenFunction::emitConvertedRValue()that acceptsConversionPair- this sounds like the best approach to me, but seems to be a lot of work and may require more refactoring to avoid code duplication. - Move logic for
needsCustomConversion()into Sema, and re-write entireCollectionUpcastConversionExprintoApplyExpr- sounds simple to implement, but this sounds like a SILGen logic, unrelated to Sema.
So far, I've tried the first approach, and I've faced an assertion when trying to create a ParamDecl of PrimaryArchetypeType in the following test case:
private func arrayUpCast<Ct: Base>(_ arr: [Ct]) -> [Base] {
return arr
}
(collection_upcast_expr implicit type="[Base]" location=foo.swift:21:10 range=[foo.swift:21:10 - line:21:10]
(declref_expr type="[Ct]" location=foo.swift:21:10 range=[foo.swift:21:10 - line:21:10] decl="MyCLI.(file).arrayUpCast(_:).arr@foo.swift:19:38" function_ref=unapplied)
(value_conversion=archetype_to_super_expr implicit type="Base" location=foo.swift:21:10 range=[foo.swift:21:10 - line:21:10]
(opaque_value_expr implicit type="Ct" location=foo.swift:21:10 range=[foo.swift:21:10 - line:21:10] 0x8304eadc0)))
What is the difference between PrimaryArchetypeType and GenericTypeParamType?
What is the correct way to transform one into another? Would usage of GenericTypeParamType instead of PrimaryArchetypeType inside key/value conversions lead to los of information? Aside from saving memory, does ConversionPair have other advantages over ClosureExpr?