Skip to content

Commit 485a107

Browse files
committed
inference: follow up the Vararg fix in abstract_call_unionall
Follows up #51393.
1 parent c22adc0 commit 485a107

File tree

2 files changed

+40
-30
lines changed

2 files changed

+40
-30
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,44 +1853,46 @@ 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+
na == 3 || return CallMeta(Any, EFFECTS_THROWS, call.info)
1859+
a2 = argtypes[2]
1860+
a3 = unwrapva(argtypes[3])
1861+
nothrow = false
1862+
elseif na == 3
18581863
a2 = argtypes[2]
18591864
a3 = argtypes[3]
18601865
= (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]
1866+
nothrow = a2 ᵢ TypeVar && (a3 ᵢ Type || a3 ᵢ TypeVar)
1867+
else
1868+
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1869+
end
1870+
canconst = true
1871+
if isa(a3, Const)
1872+
body = a3.val
1873+
elseif isType(a3)
1874+
body = a3.parameters[1]
1875+
canconst = false
1876+
else
1877+
return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
1878+
end
1879+
if !(isa(body, Type) || isa(body, TypeVar))
1880+
return CallMeta(Any, EFFECTS_THROWS, call.info)
1881+
end
1882+
if has_free_typevars(body)
1883+
if isa(a2, Const)
1884+
tv = a2.val
1885+
elseif isa(a2, PartialTypeVar)
1886+
tv = a2.tv
18711887
canconst = false
18721888
else
1873-
return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), call.info)
1874-
end
1875-
if !(isa(body, Type) || isa(body, TypeVar))
18761889
return CallMeta(Any, EFFECTS_THROWS, call.info)
18771890
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)
1891+
isa(tv, TypeVar) || return CallMeta(Any, EFFECTS_THROWS, call.info)
1892+
body = UnionAll(tv, body)
18921893
end
1893-
return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1894+
ret = canconst ? Const(body) : Type{body}
1895+
return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), call.info)
18941896
end
18951897

18961898
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)