Skip to content

Commit 57e70c1

Browse files
authored
inference: follow up the Vararg fix in abstract_call_unionall (#51403)
1 parent 85c96b9 commit 57e70c1

File tree

2 files changed

+44
-30
lines changed

2 files changed

+44
-30
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,44 +1853,50 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, (; fargs
18531853
end
18541854

18551855
function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{Any}, call::CallMeta)
1856-
if length(argtypes) == 3
1857-
canconst = true
1856+
na = length(argtypes)
1857+
if isvarargtype(argtypes[end])
1858+
if na 2
1859+
return CallMeta(Any, EFFECTS_THROWS, call.info)
1860+
elseif na > 4
1861+
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1862+
end
1863+
a2 = argtypes[2]
1864+
a3 = unwrapva(argtypes[3])
1865+
nothrow = false
1866+
elseif na == 3
18581867
a2 = argtypes[2]
18591868
a3 = argtypes[3]
18601869
= (typeinf_lattice(interp))
1861-
if isvarargtype(a3)
1862-
a3 = unwrapva(a3)
1863-
nothrow = false
1864-
else
1865-
nothrow = a2 ᵢ TypeVar && (a3 ᵢ Type || a3 ᵢ TypeVar)
1866-
end
1867-
if isa(a3, Const)
1868-
body = a3.val
1869-
elseif isType(a3)
1870-
body = a3.parameters[1]
1870+
nothrow = a2 ᵢ TypeVar && (a3 ᵢ Type || a3 ᵢ TypeVar)
1871+
else
1872+
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1873+
end
1874+
canconst = true
1875+
if isa(a3, Const)
1876+
body = a3.val
1877+
elseif isType(a3)
1878+
body = a3.parameters[1]
1879+
canconst = false
1880+
else
1881+
return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
1882+
end
1883+
if !(isa(body, Type) || isa(body, TypeVar))
1884+
return CallMeta(Any, EFFECTS_THROWS, call.info)
1885+
end
1886+
if has_free_typevars(body)
1887+
if isa(a2, Const)
1888+
tv = a2.val
1889+
elseif isa(a2, PartialTypeVar)
1890+
tv = a2.tv
18711891
canconst = false
18721892
else
1873-
return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
1874-
end
1875-
if !(isa(body, Type) || isa(body, TypeVar))
18761893
return CallMeta(Any, EFFECTS_THROWS, call.info)
18771894
end
1878-
if has_free_typevars(body)
1879-
if isa(a2, Const)
1880-
tv = a2.val
1881-
elseif isa(a2, PartialTypeVar)
1882-
tv = a2.tv
1883-
canconst = false
1884-
else
1885-
return CallMeta(Any, EFFECTS_THROWS, call.info)
1886-
end
1887-
isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, call.info)
1888-
body = UnionAll(tv, body)
1889-
end
1890-
ret = canconst ? Const(body) : Type{body}
1891-
return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), call.info)
1895+
isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, call.info)
1896+
body = UnionAll(tv, body)
18921897
end
1893-
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1898+
ret = canconst ? Const(body) : Type{body}
1899+
return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), call.info)
18941900
end
18951901

18961902
function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, si::StmtInfo, sv::AbsIntState)

test/compiler/inference.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5235,3 +5235,11 @@ end |> only == Val{true}
52355235
@test code_typed() do
52365236
b{c} = d...
52375237
end |> only |> first isa Core.CodeInfo
5238+
5239+
abstract_call_unionall_vararg(some::Some{Any}) = UnionAll(some.value...)
5240+
@test only(Base.return_types(abstract_call_unionall_vararg)) !== Union{}
5241+
let TV = TypeVar(:T)
5242+
t = Vector{TV}
5243+
some = Some{Any}((TV, t))
5244+
@test abstract_call_unionall_vararg(some) isa UnionAll
5245+
end

0 commit comments

Comments
 (0)