How to combine @nospecialize with type parameters?

It seems that type parameters in functions prevent @nospecialize from having an effect:

julia> f(@nospecialize x::T) where T = 0;

julia> f(1); f(1.0);

julia> m = only(methods(f)); m.specializations |> collect
7-element Vector{Any}:
 MethodInstance for f(::Int64)
 MethodInstance for f(::Float64)
 nothing
 nothing
 nothing
 nothing
 nothing

Is there a way to get around this? In the example above, one could write

f(@nospecialize x::T where T) = 0

or drop the T altogether. However, what about methods where the type parameter occurs in several arguments, as in

f(x::T, y::T) where T = 0

So far, method parameters are always specialized in the compiled method, even when just named as part of the parameter sequence instead of being used in the method body:

Function over-specialization on unused parts of types · Issue #26834 · JuliaLang/julia

…or specifying a shared value of annotation parameters during dispatch.

That evaluates to Any. The @nospecialize effect you’re going for does happen with a named parametric type like Vector{T} where T.

The method static parameter may be eliminated from that particular example like so:

f((x, y)::(Vararg{T, 2} where {T})) = 0

AFK, did not test the above. In principle it should work.

That’s a valid definition (interesting!). I’ve tried it out: when combined @nospecialize it specializes like a method with a type parameter. (Since @nospecialize doesn’t like the (x, y), it has to be put at the beginning of the function body.)