diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 71dcd0ff97ea0..a8f1726e9f0fc 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1741,6 +1741,17 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K, canconst = true tparams = Any[] outervars = TypeVar[] + + # first push the tailing vars from headtype into outervars + outer_start, ua = 0, headtype + while isa(ua, UnionAll) + if (outer_start += 1) > largs + push!(outervars, ua.var) + end + ua = ua.body + end + outer_start = outer_start - largs + 1 + varnamectr = 1 ua = headtype for i = 1:largs @@ -1759,9 +1770,16 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K, uncertain = true unw = unwrap_unionall(ai) isT = isType(unw) - if isT && isa(ai,UnionAll) && contains_is(outervars, ai.var) - ai = rename_unionall(ai) - unw = unwrap_unionall(ai) + if isT + tai = ai + while isa(tai, UnionAll) + if contains_is(outervars, tai.var) + ai = rename_unionall(ai) + unw = unwrap_unionall(ai) + break + end + tai = tai.body + end end ai_w = widenconst(ai) ub = ai_w isa Type && ai_w <: Type ? instanceof_tfunc(ai)[1] : Any @@ -1822,7 +1840,7 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K, return Type{<:appl} end ans = Type{appl} - for i = length(outervars):-1:1 + for i = length(outervars):-1:outer_start ans = UnionAll(outervars[i], ans) end return ans diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index b136f91db8ca2..841add157e5f9 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2743,6 +2743,7 @@ let 𝕃 = Core.Compiler.fallback_lattice @test apply_type_tfunc(𝕃, Const(Issue47089), A, A) <: (Type{Issue47089{A,B}} where {A<:Integer, B<:Integer}) end @test only(Base.return_types(keys, (Dict{String},))) == Base.KeySet{String, T} where T<:(Dict{String}) +@test only(Base.return_types((r)->similar(Array{typeof(r[])}, 1), (Base.RefValue{Array{Int}},))) == Vector{T} where T<:(Array{Int}) # PR 27351, make sure optimized type intersection for method invalidation handles typevars