swift-unidoc icon indicating copy to clipboard operation
swift-unidoc copied to clipboard

encoding of generic constraints loses information for complex bounds

Open tayloraswift opened this issue 1 year ago • 0 comments

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:

  1. T.U is 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)

  2. 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 for Array<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.

tayloraswift avatar Jun 13 '24 20:06 tayloraswift