Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ensure to show the whole type, even if the proper subset matched an alias #39728

Merged
merged 2 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 25 additions & 24 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -761,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)
Expand All @@ -784,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))
Expand Down Expand Up @@ -825,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

Expand Down
7 changes: 6 additions & 1 deletion test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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, $(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{AbstractVector{T} where T, T} where T"

@test sprint(show, :(./)) == ":((./))"
@test sprint(show, :((.|).(.&, b))) == ":((.|).((.&), b))"
Expand Down