Skip to content

Commit

Permalink
Allow UnionAll as input to subtypes and include UnionAll in its…
Browse files Browse the repository at this point in the history
… output.

Fix #20086
  • Loading branch information
yuyichao committed Jan 30, 2017
1 parent 8cc647b commit cee4323
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -298,22 +298,46 @@ enumerated types (see `@enum`).
function instances end

# subtypes
function _subtypes(m::Module, x::DataType, sts=Set{DataType}(), visited=Set{Module}())
function _subtypes(m::Module, x::Union{DataType,UnionAll},
sts=Set{Union{DataType,UnionAll}}(), visited=Set{Module}())
push!(visited, m)
if isa(x, UnionAll)
xt = unwrap_unionall(x)
if !isa(xt, DataType)
return sts
end
xt = xt::DataType
else
xt = x::DataType
end
for s in names(m, true)
if isdefined(m, s) && !isdeprecated(m, s)
t = getfield(m, s)
if isa(t, DataType) && t.name.name == s && supertype(t).name == x.name
ti = typeintersect(t, x)
ti != Bottom && push!(sts, ti)
elseif isa(t, Module) && !in(t, visited)
_subtypes(t, x, sts, visited)
if isa(t, DataType)
t = t::DataType
if t.name.name === s && supertype(t).name == xt.name
ti = typeintersect(t, x)
ti != Bottom && push!(sts, ti)
end
elseif isa(t, UnionAll)
t = t::UnionAll
tt = unwrap_unionall(t)
isa(tt, DataType) || continue
tt = tt::DataType
if tt.name.name === s && supertype(tt).name == xt.name
ti = typeintersect(t, x)
ti != Bottom && push!(sts, ti)
end
elseif isa(t, Module)
t = t::Module
in(t, visited) || _subtypes(t, x, sts, visited)
end
end
end
return sts
end
subtypes(m::Module, x::DataType) = x.abstract ? sort!(collect(_subtypes(m, x)), by=string) : DataType[]
subtypes(m::Module, x::DataType) = x.abstract ? sort!(collect(_subtypes(m, x)), by=string) : Union{DataType,UnionAll}[]
subtypes(m::Module, x::UnionAll) = sort!(collect(_subtypes(m, x)), by=string)

"""
subtypes(T::DataType)
Expand All @@ -330,7 +354,7 @@ julia> subtypes(Integer)
Unsigned
```
"""
subtypes(x::DataType) = subtypes(Main, x)
subtypes(x::Union{DataType,UnionAll}) = subtypes(Main, x)

function to_tuple_type(t::ANY)
@_pure_meta
Expand Down

0 comments on commit cee4323

Please sign in to comment.