as you can see, this function returns an Array of lovely concrete type. The same works for missing by the way.

However if I define my own type, lets say a singleton type like Nothing, type inference is not able to get it, but infers Any instead of the lovely Union seen above.

I hope that this is not hardcoded somewhere in the typeinference, but that I only need to overwrite some helper functionalities within Base to make the inference work properly. Does someone know which things to overload?

I tried to overload Base.promote_rule, however it does not change the above results at all. Hopefully there is some other hidden gem.

By now I tried to mimic all of promote_rule stuff from Nothing

nonmysingleton(::Type{T}) where {T} = Core.Compiler.typesubtract(T, MySingleton)
Base.promote_rule(T::Type{MySingleton}, S::Type) = Union{S, MySingleton}
# CAUTION: this leads to method ambiguities
function Base.promote_rule(T::Type{>:MySingleton}, S::Type)
R = nonmysingleton(T)
Core.println("R = $R")
R >: T && return Any
T = R
R = promote_type(T, S)
return Union{R, MySingleton}
end
Base.promote_type(T::Type{MySingleton}, S::Type) = Union{S, MySingleton}
Base.convert(::Type{T}, x::T) where {T>:MySingleton} = x
Base.convert(::Type{T}, x) where {T>:MySingleton} = convert(nonmysingleton(T), x)
# EDIT: together with the following two lines it works
Base.promote_typejoin(::Type{MySingleton}, T::Type) = Union{T, MySingleton}
Base.promote_typejoin(T::Type, ::Type{MySingleton}) = Union{T, MySingleton}

but still does not work…
(the Core.println actually does not print anything, hence does not get called)

It looks like Base.promote_typejoin has some special behavior for Nothing and Missing. You should be able to implement the same thing for your type by following that example, although I’m not entirely sure that’s the right thing to do.

Thanks a lot, adding two Base.promote_typejoin rules solved it,

however now from time to time I get errors, that method resolution is ambiguous now. I think this is be design and denoted by the implementation of missing

as you can see, missing is indeed not only implementing promotion for missing, but also accounts for interactions with nothing. I.e. it seems if you want to add a new type like MySingleton you have not only to add the methods above, but you have to model the interactions with all other such types like nothing and missing from Base.

This together with Base._promote_type implementation actually looks like hardcoded to me… you can hack arround but rather complicated and non-intuitive… a bit unfortunate