diff --git a/base/reflection.jl b/base/reflection.jl index 03f3627bd6a10..35a469c320107 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -74,7 +74,31 @@ function_name(f::Function) = isgeneric(f) ? f.env.name : (:anonymous) code_lowered(f::Function,t::Tuple) = map(m->uncompressed_ast(m.func.code), methods(f,t)) methods(f::ANY,t::ANY) = map(m->m[3], _methods(f,t,-1))::Array{Any,1} -_methods(f::ANY,t::ANY,lim) = ccall(:jl_matching_methods, Any, (Any,Any,Int32), f, t, lim) +_methods(f::ANY,t::ANY,lim) = _methods(f,{(t::Tuple)...},length(t::Tuple),lim,{}) +function _methods(f::ANY,t::Array,i,lim::Integer,matching::Array{Any,1}) + if i == 0 + new = ccall(:jl_matching_methods, Any, (Any,Any,Int32), f, tuple(t...), lim) + if new === false + return false + end + append!(matching, new::Array{Any,1}) + else + ti = t[i] + if isa(ti, UnionType) + for ty in (ti::UnionType).types + t[i] = ty + if _methods(f,t,i-1,lim,matching) === false + t[i] = ty + return false + end + end + t[i] = ti + else + return _methods(f,t,i-1,lim,matching) + end + end + matching +end function methods(f::Function) if !isgeneric(f) diff --git a/test/core.jl b/test/core.jl index 5eaf336aae8c7..e2b841d6d0bf5 100644 --- a/test/core.jl +++ b/test/core.jl @@ -916,3 +916,17 @@ end @test isa(foo4075(Foo4075(int64(1),2.0),:y), Float64) # very likely to segfault the second time if this is broken @test isa(foo4075(Foo4075(int64(1),2.0),:y), Float64) + +# issue #3167 +function foo(x) + ret=Array(typeof(x[1]), length(x)) + for j = 1:length(x) + ret[j] = x[j] + end + return ret +end +x = Array(Union(Dict{Int64,String},Array{Int64,3},Number,String,Nothing), 3) +x[1] = 1.0 +x[2] = 2.0 +x[3] = 3.0 +foo(x) == [1.0, 2.0, 3.0]