Type signature disambiguations do not take into account same-type generic constraints when substituting Self #38

Open
opened 2025-10-14 15:46:35 -06:00 by navan · 0 comments
Owner

Originally created by @tayloraswift on 1/2/2025

this is a hole that is originally caused by the Swift compiler bug https://github.com/swiftlang/swift/issues/78343 , but is not sufficiently patched by Unidoc’s downstream heuristics.

specifically, given two extensions like these

struct S<T> {}

extension S<Int> 
{
    static var x:Self { get }
}
extension S<String> 
{
    static var x:Self { get }
}

the Swift compiler will fail to resolve the Self tokens, and Unidoc’s heuristic steps in, replacing Self with S<T>. however, this substitution has no disambiguative value, as it is identical between both extensions.

the client workaround is to avoid Self and spell these extensions using the actual resolved types:

extension S<Int> 
{
-   static var x:Self { get }
+   static var x:S<Int> { get }
}
extension S<String> 
{
-   static var x:Self { get }
+   static var x:S<String> { get }
}

this would allow documentation to disambiguate between the two overloads with

-  ``S.x -> S<Int>``
-  ``S.x -> S<String>``

in theory, Unidoc could inspect the generic constraints and substitute the type arguments itself. but at this point, we are layering heuristics upon heuristics in order to compensate for what is really a plain old Swift compiler bug.

*Originally created by @tayloraswift on 1/2/2025* this is a hole that is originally caused by the Swift compiler bug https://github.com/swiftlang/swift/issues/78343 , but is not sufficiently patched by Unidoc’s downstream heuristics. specifically, given two extensions like these ```swift struct S<T> {} extension S<Int> { static var x:Self { get } } extension S<String> { static var x:Self { get } } ``` the Swift compiler will fail to resolve the `Self` tokens, and Unidoc’s heuristic steps in, replacing `Self` with `S<T>`. however, this substitution has no disambiguative value, as it is identical between both extensions. the client workaround is to avoid `Self` and spell these extensions using the actual resolved types: ```diff extension S<Int> { - static var x:Self { get } + static var x:S<Int> { get } } extension S<String> { - static var x:Self { get } + static var x:S<String> { get } } ``` this would allow documentation to disambiguate between the two overloads with ```markdown - ``S.x -> S<Int>`` - ``S.x -> S<String>`` ``` in theory, Unidoc could inspect the generic constraints and substitute the type arguments itself. but at this point, we are layering heuristics upon heuristics in order to compensate for what is really a plain old Swift compiler bug.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github/swift-unidoc#38
No description provided.