Skip to content

Commit

Permalink
fix tuple_tfunc on Union containing Type{...} (#44725)
Browse files Browse the repository at this point in the history
fix #44705
  • Loading branch information
aviatesk authored Mar 30, 2022
1 parent 4b58679 commit 4115686
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
6 changes: 6 additions & 0 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,10 @@ function tuple_tfunc(argtypes::Vector{Any})
params[i] = typeof(x.val)
else
x = isvarargtype(x) ? x : widenconst(x)
# since there don't exist any values whose runtime type are `Tuple{Type{...}}`,
# here we should turn such `Type{...}`-parameters to valid parameters, e.g.
# (::Type{Int},) -> Tuple{DataType} (or PartialStruct for more accuracy)
# (::Union{Type{Int32},Type{Int64}}) -> Tuple{Type}
if isType(x)
anyinfo = true
xparam = x.parameters[1]
Expand All @@ -1554,6 +1558,8 @@ function tuple_tfunc(argtypes::Vector{Any})
else
params[i] = Type
end
elseif !isvarargtype(x) && hasintersect(x, Type)
params[i] = Union{x, Type}
else
params[i] = x
end
Expand Down
11 changes: 10 additions & 1 deletion test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,15 @@ end
@test arraysize_tfunc(Vector, Float64) === Union{}
@test arraysize_tfunc(String, Int) === Union{}

let tuple_tfunc
function tuple_tfunc(@nospecialize xs...)
return Core.Compiler.tuple_tfunc(Any[xs...])
end
@test Core.Compiler.widenconst(tuple_tfunc(Type{Int})) === Tuple{DataType}
# https://github.com/JuliaLang/julia/issues/44705
@test tuple_tfunc(Union{Type{Int32},Type{Int64}}) === Tuple{Type}
end

function f23024(::Type{T}, ::Int) where T
1 + 1
end
Expand Down Expand Up @@ -2082,7 +2091,7 @@ let M = Module()
obj = $(Expr(:new, M.BePartialStruct, 42, :cond))
r1 = getfield(obj, :cond) ? 0 : a # r1::Union{Nothing,Int}, not r1::Int (because PartialStruct doesn't wrap Conditional)
a = $(gensym(:anyvar))::Any
r2 = getfield(obj, :cond) ? a : nothing # r2::Any, not r2::Const(nothing) (we don't need to worry about constrait invalidation here)
r2 = getfield(obj, :cond) ? a : nothing # r2::Any, not r2::Const(nothing) (we don't need to worry about constraint invalidation here)
return r1, r2 # ::Tuple{Union{Nothing,Int},Any}
end |> only
end
Expand Down

0 comments on commit 4115686

Please sign in to comment.