diff --git a/src/mangling.jl b/src/mangling.jl index f681c7f9..9272f05a 100644 --- a/src/mangling.jl +++ b/src/mangling.jl @@ -120,10 +120,14 @@ function mangle_param(@nospecialize(t), substitutions = Any[], top = false) mangle_param(Base.unwrap_unionall(t), substitutions) elseif isa(t, Core.TypeofVararg) T = isdefined(t, :T) ? t.T : Any - if isdefined(t, :N) + # `N` is a `TypeVar` when the length is still parametric, which is what unwrapping a + # `UnionAll` such as `NTuple{N,Int}` leaves behind. There is no count to repeat then, + # so the type is mangled like the unbounded `Vararg{T}` it is equal to. + N = isdefined(t, :N) && isa(t.N, Integer) ? t.N : nothing + if N !== nothing # For NTuple, repeat the type as needed str = "" - for _ in 1:t.N + for _ in 1:N str *= mangle_param(T, substitutions) end str diff --git a/test/utils.jl b/test/utils.jl index e822506f..6477f02a 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -100,6 +100,10 @@ end @test mangle(identity, Tuple{1, 2}, Tuple{}, Tuple) == "identity(Tuple<1, 2>, Tuple<>, Tuple)" @test mangle(identity, NTuple{2, Int}) == "identity(Tuple)" @test mangle(identity, Tuple{Vararg{Int}}) == "identity(Tuple<>)" + # A `Vararg` whose length is still a `TypeVar`, which is what unwrapping a `UnionAll` + # leaves behind. It is the same type as the unbounded `Vararg` above, so it mangles alike. + @test mangle(identity, NTuple{N, Int} where {N}) == "identity(Tuple<>)" + @test mangle(identity, Val{NTuple{N, Int} where {N}}) == "identity(Val>)" # many substitutions @test mangle(identity, Val{1}, Val{2}, Val{3}, Val{4}, Val{5}, Val{6}, Val{7}, Val{8},