Skip to content

Commit

Permalink
inference: follow up the Vararg fix in abstract_call_unionall
Browse files Browse the repository at this point in the history
Follows up #51393.
  • Loading branch information
aviatesk committed Sep 21, 2023
1 parent 6023370 commit 6fa43a4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 30 deletions.
66 changes: 36 additions & 30 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1853,44 +1853,50 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, (; fargs
end

function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{Any}, call::CallMeta)
if length(argtypes) == 3
canconst = true
na = length(argtypes)
if isvarargtype(argtypes[end])
if na 2
return CallMeta(Any, EFFECTS_THROWS, call.info)
elseif na > 4
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
end
a2 = argtypes[2]
a3 = unwrapva(argtypes[3])
nothrow = false
elseif na == 3
a2 = argtypes[2]
a3 = argtypes[3]
= (typeinf_lattice(interp))
if isvarargtype(a3)
a3 = unwrapva(a3)
nothrow = false
else
nothrow = a2 ᵢ TypeVar && (a3 ᵢ Type || a3 ᵢ TypeVar)
end
if isa(a3, Const)
body = a3.val
elseif isType(a3)
body = a3.parameters[1]
nothrow = a2 ᵢ TypeVar && (a3 ᵢ Type || a3 ᵢ TypeVar)
else
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
end
canconst = true
if isa(a3, Const)
body = a3.val
elseif isType(a3)
body = a3.parameters[1]
canconst = false
else
return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
end
if !(isa(body, Type) || isa(body, TypeVar))
return CallMeta(Any, EFFECTS_THROWS, call.info)
end
if has_free_typevars(body)
if isa(a2, Const)
tv = a2.val
elseif isa(a2, PartialTypeVar)
tv = a2.tv
canconst = false
else
return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
end
if !(isa(body, Type) || isa(body, TypeVar))
return CallMeta(Any, EFFECTS_THROWS, call.info)
end
if has_free_typevars(body)
if isa(a2, Const)
tv = a2.val
elseif isa(a2, PartialTypeVar)
tv = a2.tv
canconst = false
else
return CallMeta(Any, EFFECTS_THROWS, call.info)
end
isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, call.info)
body = UnionAll(tv, body)
end
ret = canconst ? Const(body) : Type{body}
return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), call.info)
isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, call.info)
body = UnionAll(tv, body)
end
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
ret = canconst ? Const(body) : Type{body}
return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), call.info)
end

function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, si::StmtInfo, sv::AbsIntState)
Expand Down
8 changes: 8 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5235,3 +5235,11 @@ end |> only == Val{true}
@test code_typed() do
b{c} = d...
end |> only |> first isa Core.CodeInfo

abstract_call_unionall_vararg(some::Some{Any}) = UnionAll(some.value...)
@test only(Base.return_types(abstract_call_unionall_vararg)) !== Union{}
let TV = TypeVar(:T)
t = Vector{TV}
some = Some{Any}((TV, t))
@test abstract_call_unionall_vararg(some) isa UnionAll
end

0 comments on commit 6fa43a4

Please sign in to comment.