From 9d31e594a025c30c0fb379d02d7696cf77624af0 Mon Sep 17 00:00:00 2001 From: Joe Petviashvili Date: Mon, 16 Jan 2017 21:50:00 -0800 Subject: [PATCH 1/3] get subtypes() of UnionAll --- base/reflection.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/base/reflection.jl b/base/reflection.jl index 0cf01a6289615..b763416a8eb29 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -314,6 +314,7 @@ function _subtypes(m::Module, x::DataType, sts=Set{DataType}(), visited=Set{Modu return sts end subtypes(m::Module, x::DataType) = sort(collect(_subtypes(m, x)), by=string) +subtypes(m::Module, x::UnionAll) = subtypes(m, unwrap_unionall(x)) """ subtypes(T::DataType) @@ -331,6 +332,7 @@ julia> subtypes(Integer) ``` """ subtypes(x::DataType) = subtypes(Main, x) +subtypes(x::UnionAll) = subtypes(unwrap_unionall(x)) function to_tuple_type(t::ANY) @_pure_meta From e5a77685d40a0281832a0755a01fbe209ea6e43f Mon Sep 17 00:00:00 2001 From: Joe Petviashvili Date: Tue, 17 Jan 2017 13:05:30 -0800 Subject: [PATCH 2/3] add _subtypes() for UnionAll --- base/reflection.jl | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index b763416a8eb29..1f5568d6e8447 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -303,7 +303,25 @@ function _subtypes(m::Module, x::DataType, sts=Set{DataType}(), visited=Set{Modu 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 + if isa(t, DataType) && supertype(t) == x + ti = typeintersect(t, x) + ti != Bottom && push!(sts, ti) + elseif isa(t, UnionAll) && isa(unwrap_unionall(t), DataType) + ti = typeintersect(t, x) + ti != Bottom && supertype(ti) == x && push!(sts, ti) + elseif isa(t, Module) && !in(t, visited) + _subtypes(t, x, sts, visited) + end + end + end + return sts +end +function _subtypes(m::Module, x::UnionAll, sts=Set{UnionAll}(), visited=Set{Module}()) + push!(visited, m) + for s in names(m, true) + if isdefined(m, s) && !isdeprecated(m, s) + t = getfield(m, s) + if isa(t, UnionAll) && isa(unwrap_unionall(t), DataType) && supertype(t) == x ti = typeintersect(t, x) ti != Bottom && push!(sts, ti) elseif isa(t, Module) && !in(t, visited) @@ -314,7 +332,7 @@ function _subtypes(m::Module, x::DataType, sts=Set{DataType}(), visited=Set{Modu return sts end subtypes(m::Module, x::DataType) = sort(collect(_subtypes(m, x)), by=string) -subtypes(m::Module, x::UnionAll) = subtypes(m, unwrap_unionall(x)) +subtypes(m::Module, x::UnionAll) = sort(collect(_subtypes(m, x)), by=string) """ subtypes(T::DataType) @@ -332,7 +350,7 @@ julia> subtypes(Integer) ``` """ subtypes(x::DataType) = subtypes(Main, x) -subtypes(x::UnionAll) = subtypes(unwrap_unionall(x)) +subtypes(x::UnionAll) = subtypes(Main, x) function to_tuple_type(t::ANY) @_pure_meta From cd83c5c504328b791dc320d72e26d67d264c4565 Mon Sep 17 00:00:00 2001 From: Joe Petviashvili Date: Tue, 17 Jan 2017 13:07:07 -0800 Subject: [PATCH 3/3] test subtypes(::UnionAll) --- test/reflection.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/reflection.jl b/test/reflection.jl index 65614e68b90a9..a7f4832abb78d 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -610,3 +610,10 @@ end @generated f18883() = nothing @test !isempty(sprint(io->code_llvm(io, f18883, Tuple{}))) @test !isempty(sprint(io->code_native(io, f18883, Tuple{}))) + +# Issue #20086 +@test subtypes(Integer) == Type[BigInt, Bool, Signed, Unsigned] +abstract A212323{T} +immutable B212323{T} <: A212323{T} end +@test subtypes(A212323) == Type[B212323] +@test subtypes(A212323{Int}) == Type[B212323{Int}]