From 546aea8bce5a68fc45fd42f6741f8c647b0d8fb2 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 13 Apr 2022 14:27:24 -0400 Subject: [PATCH] add tuple type printing with `Vararg`, and port to static_show --- base/show.jl | 26 +++++++++++++++++++------- src/rtutils.c | 38 ++++++++++++++++++++++++++++++++------ test/show.jl | 2 ++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/base/show.jl b/base/show.jl index fdf6470f4a881..3a5065a62d203 100644 --- a/base/show.jl +++ b/base/show.jl @@ -993,19 +993,31 @@ function show_datatype(io::IO, x::DataType, wheres::Vector{TypeVar}=TypeVar[]) istuple = x.name === Tuple.name n = length(parameters) - # Print homogeneous tuples with more than 3 elements compactly as NTuple{N, T} + # Print tuple types with homogeneous tails longer than max_n compactly using `NTuple` or `Vararg` + max_n = 3 if istuple - if n > 3 && all(@nospecialize(i) -> (parameters[1] === i), parameters) + taillen = 1 + for i in (n-1):-1:1 + if parameters[i] === parameters[n] + taillen += 1 + else + break + end + end + if n == taillen > max_n print(io, "NTuple{", n, ", ") show(io, parameters[1]) print(io, "}") else print(io, "Tuple{") - # join(io, params, ", ") params but `show` it - first = true - for param in parameters - first ? (first = false) : print(io, ", ") - show(io, param) + for i = 1:(taillen > max_n ? n-taillen : n) + i > 1 && print(io, ", ") + show(io, parameters[i]) + end + if taillen > max_n + print(io, ", Vararg{") + show(io, parameters[n]) + print(io, ", ", taillen, "}") end print(io, "}") end diff --git a/src/rtutils.c b/src/rtutils.c index ec0aedc2acfb2..f3a2e745ed651 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -785,6 +785,37 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt jl_sym_t *sym = globfunc ? globname : dv->name->name; char *sn = jl_symbol_name(sym); size_t quote = 0; + if (dv->name == jl_tuple_typename) { + if (dv == jl_tuple_type) + return jl_printf(out, "Tuple"); + int taillen = 1, tlen = jl_nparams(dv), i; + for (i = tlen-2; i >= 0; i--) { + if (jl_tparam(dv, i) == jl_tparam(dv, tlen-1)) + taillen++; + else + break; + } + if (taillen == tlen && taillen > 3) { + n += jl_printf(out, "NTuple{%d, ", tlen); + n += jl_static_show_x(out, jl_tparam0(dv), depth); + n += jl_printf(out, "}"); + } + else { + n += jl_printf(out, "Tuple{"); + for (i = 0; i < (taillen > 3 ? tlen-taillen : tlen); i++) { + if (i > 0) + n += jl_printf(out, ", "); + n += jl_static_show_x(out, jl_tparam(dv, i), depth); + } + if (taillen > 3) { + n += jl_printf(out, ", Vararg{"); + n += jl_static_show_x(out, jl_tparam(dv, tlen-1), depth); + n += jl_printf(out, ", %d}", taillen); + } + n += jl_printf(out, "}"); + } + return n; + } if (globfunc) { n += jl_printf(out, "typeof("); } @@ -804,9 +835,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt n += jl_printf(out, ")"); } } - if (dv->parameters && (jl_value_t*)dv != dv->name->wrapper && - (jl_has_free_typevars(v) || - (jl_value_t*)dv != (jl_value_t*)jl_tuple_type)) { + if (dv->parameters && (jl_value_t*)dv != dv->name->wrapper) { size_t j, tlen = jl_nparams(dv); if (tlen > 0) { n += jl_printf(out, "{"); @@ -818,9 +847,6 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt } n += jl_printf(out, "}"); } - else if (dv->name == jl_tuple_typename) { - n += jl_printf(out, "{}"); - } } } else if (vt == jl_intrinsic_type) { diff --git a/test/show.jl b/test/show.jl index 7ad2c96d0843f..48768c6e2c8be 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1338,6 +1338,8 @@ test_repr("(:).a") @test repr(NTuple{7,Int64}) == "NTuple{7, Int64}" @test repr(Tuple{Float64, Float64, Float64, Float64}) == "NTuple{4, Float64}" @test repr(Tuple{Float32, Float32, Float32}) == "Tuple{Float32, Float32, Float32}" +@test repr(Tuple{String, Int64, Int64, Int64}) == "Tuple{String, Int64, Int64, Int64}" +@test repr(Tuple{String, Int64, Int64, Int64, Int64}) == "Tuple{String, Vararg{Int64, 4}}" @testset "issue #42931" begin @test repr(NTuple{4, :A}) == "NTuple{4, :A}"