From b72966751e13f6e4c7571b33d3675d225d29d940 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 18 Feb 2021 01:59:49 -0500 Subject: [PATCH 1/2] ensure to show the whole type, even if the proper subset matched an alias This code should only have been active for make_typealiases, but #38099 already fixed that better, so we can just remove this now. Fixes #39723 --- base/show.jl | 22 +++++----------------- test/show.jl | 7 ++++++- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/base/show.jl b/base/show.jl index 6b6d0e1ebe83a..01e6afc5f7f4b 100644 --- a/base/show.jl +++ b/base/show.jl @@ -522,26 +522,12 @@ function makeproper(io::IO, x::Type) end end end - if x isa Union - y = [] - normal = true - for typ in uniontypes(x) - if isa(typ, TypeVar) - normal = false - else - push!(y, typ) - end - end - if !normal - properx = rewrap_unionall(Union{y...}, properx) - end - end has_free_typevars(properx) && return Any return properx end function make_typealias(@nospecialize(x::Type)) - Any <: x && return + Any === x && return x <: Tuple && return mods = modulesof!(Set{Module}(), x) Core in mods && push!(mods, Base) @@ -681,7 +667,7 @@ function show_typealias(io::IO, x::Type) end function make_typealiases(@nospecialize(x::Type)) - Any <: x && return Core.svec(), Union{} + Any === x && return Core.svec(), Union{} x <: Tuple && return Core.svec(), Union{} mods = modulesof!(Set{Module}(), x) Core in mods && push!(mods, Base) @@ -701,7 +687,9 @@ function make_typealiases(@nospecialize(x::Type)) if alias isa Type && !has_free_typevars(alias) && !print_without_params(alias) && !(alias <: Tuple) (ti, env) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), x, alias)::SimpleVector ti === Union{} && continue - mod in modulesof!(Set{Module}(), alias) || continue # make sure this alias wasn't from an unrelated part of the Union + # make sure this alias wasn't from an unrelated part of the Union + mod2 = modulesof!(Set{Module}(), alias) + mod in mod2 || (mod === Base && Core in mods) || continue env = env::SimpleVector applied = alias if !isempty(env) diff --git a/test/show.jl b/test/show.jl index bf820734c809b..06af7f2a4e1c1 100644 --- a/test/show.jl +++ b/test/show.jl @@ -2071,12 +2071,13 @@ end end module M37012 -export AValue, B2 +export AValue, B2, SimpleU struct AnInteger{S<:Integer} end struct AStruct{N} end const AValue{S} = Union{AStruct{S}, AnInteger{S}} struct BStruct{T,S} end const B2{S,T} = BStruct{T,S} +const SimpleU = Union{AnInteger, AStruct, BStruct} end @test Base.make_typealias(M37012.AStruct{1}) === nothing @test isempty(Base.make_typealiases(M37012.AStruct{1})[1]) @@ -2086,6 +2087,10 @@ end @test string(M37012.BStruct{T, T} where T) == "$(curmod_prefix)M37012.B2{T, T} where T" @test string(M37012.BStruct{T, S} where {T<:Unsigned, S<:Signed}) == "$(curmod_prefix)M37012.B2{S, T} where {T<:Unsigned, S<:Signed}" @test string(M37012.BStruct{T, S} where {T<:Signed, S<:T}) == "$(curmod_prefix)M37012.B2{S, T} where {T<:Signed, S<:T}" +@test string(Union{M37012.SimpleU, Nothing}) == "Union{Nothing, $(curmod_prefix)M37012.SimpleU}" +@test string(Union{M37012.SimpleU, Nothing, T} where T) == "Union{Nothing, T, $(curmod_prefix)M37012.SimpleU} where T" +@test string(Union{AbstractVector{T}, T} where T) == "Union{AbstractVector{T}, T} where T" +@test string(Union{AbstractVector, T} where T) == "Union{T, AbstractVector{T} where T} where T" @test sprint(show, :(./)) == ":((./))" @test sprint(show, :((.|).(.&, b))) == ":((.|).((.&), b))" From edd3c8790abb684cd1dd90a474cfa074059821fa Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 18 Feb 2021 02:25:04 -0500 Subject: [PATCH 2/2] when showing union aliases, keep TypeVars last --- base/show.jl | 27 ++++++++++++++++++++------- test/show.jl | 4 ++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/base/show.jl b/base/show.jl index 01e6afc5f7f4b..cda3661ece11f 100644 --- a/base/show.jl +++ b/base/show.jl @@ -749,16 +749,21 @@ end function show_unionaliases(io::IO, x::Union) properx = makeproper(io, x) aliases, applied = make_typealiases(properx) + isempty(aliases) && return false first = true + tvar = false for typ in uniontypes(x) - if !isa(typ, TypeVar) && rewrap_unionall(typ, properx) <: applied + if isa(typ, TypeVar) + tvar = true # sort bare TypeVars to the end + continue + elseif rewrap_unionall(typ, properx) <: applied continue end print(io, first ? "Union{" : ", ") first = false show(io, typ) end - if first && length(aliases) == 1 + if first && !tvar && length(aliases) == 1 alias = aliases[1] wheres = make_wheres(io, alias[2], x) show_typealias(io, alias[1], x, alias[2], wheres) @@ -772,8 +777,17 @@ function show_unionaliases(io::IO, x::Union) show_typealias(io, alias[1], x, alias[2], wheres) show_wheres(io, wheres) end + if tvar + for typ in uniontypes(x) + if isa(typ, TypeVar) + print(io, ", ") + show(io, typ) + end + end + end print(io, "}") end + return true end function show(io::IO, ::MIME"text/plain", @nospecialize(x::Type)) @@ -813,12 +827,11 @@ function _show_type(io::IO, @nospecialize(x::Type)) show_datatype(io, x) return elseif x isa Union - if get(io, :compact, true) - show_unionaliases(io, x) - else - print(io, "Union") - show_delim_array(io, uniontypes(x), '{', ',', '}', false) + if get(io, :compact, true) && show_unionaliases(io, x) + return end + print(io, "Union") + show_delim_array(io, uniontypes(x), '{', ',', '}', false) return end diff --git a/test/show.jl b/test/show.jl index 06af7f2a4e1c1..cf8a20e46302e 100644 --- a/test/show.jl +++ b/test/show.jl @@ -2088,9 +2088,9 @@ end @test string(M37012.BStruct{T, S} where {T<:Unsigned, S<:Signed}) == "$(curmod_prefix)M37012.B2{S, T} where {T<:Unsigned, S<:Signed}" @test string(M37012.BStruct{T, S} where {T<:Signed, S<:T}) == "$(curmod_prefix)M37012.B2{S, T} where {T<:Signed, S<:T}" @test string(Union{M37012.SimpleU, Nothing}) == "Union{Nothing, $(curmod_prefix)M37012.SimpleU}" -@test string(Union{M37012.SimpleU, Nothing, T} where T) == "Union{Nothing, T, $(curmod_prefix)M37012.SimpleU} where T" +@test string(Union{M37012.SimpleU, Nothing, T} where T) == "Union{Nothing, $(curmod_prefix)M37012.SimpleU, T} where T" @test string(Union{AbstractVector{T}, T} where T) == "Union{AbstractVector{T}, T} where T" -@test string(Union{AbstractVector, T} where T) == "Union{T, AbstractVector{T} where T} where T" +@test string(Union{AbstractVector, T} where T) == "Union{AbstractVector{T} where T, T} where T" @test sprint(show, :(./)) == ":((./))" @test sprint(show, :((.|).(.&, b))) == ":((.|).((.&), b))"