diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 72e02d262ea94..e0033e418ba79 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1749,14 +1749,12 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K, push!(tparams, ai.tv) else uncertain = true - # These blocks improve type info but make compilation a bit slower. - # XXX - #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) - #end + 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) + end ai_w = widenconst(ai) ub = ai_w isa Type && ai_w <: Type ? instanceof_tfunc(ai)[1] : Any if istuple @@ -1764,19 +1762,17 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K, # then this could be a Vararg type. if i == largs && ub === Any push!(tparams, Vararg) - # XXX - #elseif isT - # push!(tparams, rewrap_unionall(unw.parameters[1], ai)) + elseif isT + push!(tparams, rewrap_unionall(unw.parameters[1], ai)) else push!(tparams, Any) end - # XXX - #elseif isT - # push!(tparams, unw.parameters[1]) - # while isa(ai, UnionAll) - # push!(outervars, ai.var) - # ai = ai.body - # end + elseif isT + push!(tparams, unw.parameters[1]) + while isa(ai, UnionAll) + push!(outervars, ai.var) + ai = ai.body + end else # Is this the second parameter to a NamedTuple? if isa(uw, DataType) && uw.name === _NAMEDTUPLE_NAME && isa(ua, UnionAll) && uw.parameters[2] === ua.var diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index b7adcba297925..9d6446496e132 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -4643,6 +4643,16 @@ end end)[2] === Nothing end +# `apply_type_tfunc` accuracy for constrained type construction +# https://github.com/JuliaLang/julia/issues/47089 +import Core: Const +import Core.Compiler: apply_type_tfunc +struct Issue47089{A,B} end +let A = Type{<:Integer} + @test apply_type_tfunc(Const(T), A, A) <: (Type{T{A,B}} where {A<:Integer, B<:Integer}) +end +@test only(Base.return_types(keys, (Dict{String},))) == Base.KeySet{String, T} where T<:(Dict{String}) + # singleton_type on slot wrappers @test Base.return_types((Int,)) do x c = isa(x, Int) # ::Conditional