swift-unidoc
swift-unidoc copied to clipboard
encoding of generic constraints loses information for complex bounds
currently, Unidoc’s generics ABI is very weak; given a constraint like T.U == Array<Int>, Unidoc will only be able to identify it as T.U == Array. one implication of this is if there are two extensions with distinct constraints T.U == Array<Int>, T.U == Array<UInt>, Unidoc will be unable to distinguish them, as the type parameters to Array are lost.
there are two upstream bugs in lib/SymbolGraphGen:
-
T.Uis encoded without specifying the depth of the generic parameters, although this only affects Swift 5.10 code and earlier, as generic parameter shadowing was banned in Swift 6. (https://github.com/apple/swift/issues/64444) -
the ID of
Array<T>points to the generic type, not the concrete type with type substitutions. this was likely an intentional choice in lib/SymbolGraphGen, because we could not possibly generate documentation forArray<Int>,Array<UInt>, etc., so the generic type is a better choice of link target. however, it is unsafe to use as an identity. (https://github.com/apple/swift/issues/74406)
we can partly mitigate the problem by adding the formatted string Array<Int> to the identity of a generic constraint clause, although this is still incorrect - it cannot distinguish between types that shadow names in other modules.
fixing this is ABI-breaking for Swiftinit, as it changes the sort order of extension groups in very rare scenarios. we’ll probably need to do a second ABI break if we get an upstream fix in lib/SymbolGraphGen.