diff --git a/base/methodshow.jl b/base/methodshow.jl index fd9aa090b1f0b..fa03de7d232d1 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -2,7 +2,11 @@ # Method and method table pretty-printing -function argtype_decl(env, n, t) # -> (argname, argtype) +function argtype_decl(env, n, sig, i, nargs, isva) # -> (argname, argtype) + t = sig.parameters[i] + if i == nargs && isva && !isvarargtype(t) + t = Vararg{t,length(sig.parameters)-nargs+1} + end if isa(n,Expr) n = n.args[1] # handle n::T in arg list end @@ -30,26 +34,6 @@ function argtype_decl(env, n, t) # -> (argname, argtype) return s, string_with_env(env, t) end -function argtype_decl_vararg(env, n, t) - if isa(n, Expr) - s = string(n.args[1]) - if n.args[2].head == :... - # x... or x::T... declaration - if t.parameters[1] === Any - return string(s, "..."), "" - else - return s, string_with_env(env, t.parameters[1]) * "..." - end - elseif t == String - return s, "String" - end - end - # x::Vararg, x::Vararg{T}, or x::Vararg{T,N} declaration - s, length(n.args[2].args) < 4 ? - string_with_env(env, "Vararg{", t.parameters[1], "}") : - string_with_env(env, "Vararg{", t.parameters[1], ",", t.parameters[2], "}") -end - function arg_decl_parts(m::Method) tv = m.tvars if !isa(tv,SimpleVector) @@ -61,9 +45,8 @@ function arg_decl_parts(m::Method) file, line = "", 0 if li !== nothing argnames = li.slotnames[1:li.nargs] - s = Symbol("?") - decls = Any[argtype_decl(:tvar_env => tv, get(argnames, i, s), m.sig.parameters[i]) - for i = 1:length(m.sig.parameters)] + decls = Any[argtype_decl(:tvar_env => tv, argnames[i], m.sig, i, li.nargs, li.isva) + for i = 1:li.nargs] if isdefined(li, :def) file, line = li.def.file, li.def.line end diff --git a/src/jltypes.c b/src/jltypes.c index c3975601a4b15..7bb3ddc3aa571 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2155,28 +2155,22 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i if (nt < 0) jl_errorf("apply_type: Vararg length N is negative: %zd", nt); va = jl_tparam0(va); - if (nt == 0 || jl_is_leaf_type(va)) { + if (nt == 0 || !jl_has_typevars(va)) { if (ntp == 1) return jl_tupletype_fill(nt, va); size_t i, l; + p = jl_alloc_svec(ntp - 1 + nt); for (i = 0, l = ntp - 1; i < l; i++) { - if (!jl_is_leaf_type(iparams[i])) - break; + jl_svecset(p, i, iparams[i]); } - if (i == l) { - p = jl_alloc_svec(ntp - 1 + nt); - for (i = 0, l = ntp - 1; i < l; i++) { - jl_svecset(p, i, iparams[i]); - } - l = ntp - 1 + nt; - for (; i < l; i++) { - jl_svecset(p, i, va); - } - JL_GC_PUSH1(&p); - jl_value_t *ndt = (jl_value_t*)jl_apply_tuple_type(p); - JL_GC_POP(); - return ndt; + l = ntp - 1 + nt; + for (; i < l; i++) { + jl_svecset(p, i, va); } + JL_GC_PUSH1(&p); + jl_value_t *ndt = (jl_value_t*)jl_apply_tuple_type(p); + JL_GC_POP(); + return ndt; } } } diff --git a/test/core.jl b/test/core.jl index 2863d79efb373..d98db8c25826f 100644 --- a/test/core.jl +++ b/test/core.jl @@ -139,6 +139,8 @@ let N = TypeVar(:N,true) @test is(Bottom,typeintersect(Tuple{Array{Int,N},Vararg{Int,N}}, Tuple{Vector{Int},Real,Real,Real})) @test is(Bottom,typeintersect(Tuple{Vector{Int},Real,Real,Real}, Tuple{Array{Int,N},Vararg{Int,N}})) @test Tuple{Int,Vararg{Int,2}} == Tuple{Int,Int,Int} + @test Tuple{Int,Vararg{Int,2}} === Tuple{Int,Int,Int} + @test Tuple{Any, Any} === Tuple{Vararg{Any,2}} @test Tuple{Int,Vararg{Int,2}} == Tuple{Int,Int,Vararg{Int,1}} @test Tuple{Int,Vararg{Int,2}} == Tuple{Int,Int,Int,Vararg{Int,0}} @test !(Tuple{Int,Vararg{Int,2}} <: Tuple{Int,Int,Int,Vararg{Int,1}})