@@ -50,6 +50,41 @@ Base.promote_rule(::Type{Identity}, ::Type{Either}) = Either
5050# promote_type Either & Either
5151# -----------------------------
5252
53+ # It turns out for this symmetric case we need to define both versions of promote_rule, including the flipped one
54+ # This is needed, because `promote_type` assumes promote_rule to fallback to the general fallback returning Union{}
55+ # for its feature "you only need to define one" to work out correctly.
56+
57+ # It turns out further, that there is a major bug in Julia, not allowing for these kinds of dispatch as of now
58+ # see https://github.com/JuliaLang/julia/issues/36804 the issue and possible future updates
59+
60+ # As a workaround, we overload `promote_type` to deal with our symmetric case
61+ function Base. promote_type (:: Type{Either{L1, R1}} , :: Type{Either{L2, R2}} ) where {L1, R1, L2, R2}
62+ Base. @_inline_meta
63+ T = Either{L1, R1}
64+ S = Either{L2, R2}
65+ # we use typeintersect, as we get an Either for the non-fitting site,
66+ # thanks to Base.promote_rule(::Type{Either{L1, R1}}, ::Type{Either{L2, R2}}) where {L1, R1, L2, R2} = Either
67+ typeintersect (promote_rule (T, S), promote_rule (S, T))
68+ end
69+
70+ function Base. promote_type (:: Type{Either{<:Any, R1}} , :: Type{Either{<:Any, R2}} ) where {R1, R2}
71+ Base. @_inline_meta
72+ T = Either{<: Any , R1}
73+ S = Either{<: Any , R2}
74+ # we use typeintersect, as we get an Either for the non-fitting site,
75+ # thanks to Base.promote_rule(::Type{Either{<:Any, R1}}, ::Type{Either{<:Any, R2}}) where {R1, R2} = Either
76+ typeintersect (promote_rule (T, S), promote_rule (S, T))
77+ end
78+
79+ function Base. promote_type (:: Type{Either{L1, <:Any}} , :: Type{Either{L2, <:Any}} ) where {L1, L2}
80+ Base. @_inline_meta
81+ T = Either{L1, <: Any }
82+ S = Either{L2, <: Any }
83+ # we use typeintersect, as we get an Either for the non-fitting site,
84+ # thanks to Base.promote_rule(::Type{Either{L1, <:Any}}, ::Type{Either{L2, <:Any}}) where {L1, L2} = Either
85+ typeintersect (promote_rule (T, S), promote_rule (S, T))
86+ end
87+
5388# we need to be cautious here, as we cannot dispatch on Type{<:Either{<:Any, R}} or similar, because R might not be defined
5489Base. promote_rule (:: Type{Either{L, R}} , :: Type{Either{L, R}} ) where {L, R} = Either{L, R}
5590Base. promote_rule (:: Type{Either{L1, R}} , :: Type{Either{L2, R}} ) where {L1, R, L2 <: L1 } = Either{L1, R}
@@ -75,7 +110,6 @@ Base.promote_rule(::Type{Either{<:Any, R1}}, ::Type{Either{<:Any, R2}}) where {R
75110Base. promote_rule (:: Type{Either} , :: Type{Either} ) = Either
76111
77112
78-
79113# promote_typejoin
80114# ================
81115
0 commit comments