Skip to content

Commit 04d6d5f

Browse files
authored
inference: check argtype compatibility in abstract_call_opaque_closure (#55672)
1 parent 39f2ad1 commit 04d6d5f

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,11 +2334,16 @@ end
23342334
function abstract_call_opaque_closure(interp::AbstractInterpreter,
23352335
closure::PartialOpaque, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, check::Bool=true)
23362336
sig = argtypes_to_type(arginfo.argtypes)
2337-
result = abstract_call_method(interp, closure.source::Method, sig, Core.svec(), false, si, sv)
2338-
(; rt, edge, effects, volatile_inf_result) = result
23392337
tt = closure.typ
2340-
sigT = (unwrap_unionall(tt)::DataType).parameters[1]
2341-
match = MethodMatch(sig, Core.svec(), closure.source, sig <: rewrap_unionall(sigT, tt))
2338+
ocargsig = rewrap_unionall((unwrap_unionall(tt)::DataType).parameters[1], tt)
2339+
ocargsig′ = unwrap_unionall(ocargsig)
2340+
ocargsig′ isa DataType || return CallMeta(Any, Any, Effects(), NoCallInfo())
2341+
ocsig = rewrap_unionall(Tuple{Tuple, ocargsig′.parameters...}, ocargsig)
2342+
hasintersect(sig, ocsig) || return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
2343+
ocmethod = closure.source::Method
2344+
result = abstract_call_method(interp, ocmethod, sig, Core.svec(), false, si, sv)
2345+
(; rt, edge, effects, volatile_inf_result) = result
2346+
match = MethodMatch(sig, Core.svec(), ocmethod, sig <: ocsig)
23422347
𝕃ₚ = ipo_lattice(interp)
23432348
= (𝕃ₚ)
23442349
const_result = volatile_inf_result

test/compiler/inference.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6076,3 +6076,16 @@ end
60766076
fcondvarargs(a, b, c, d) = isa(d, Int64)
60776077
gcondvarargs(a, x...) = return fcondvarargs(a, x...) ? isa(a, Int64) : !isa(a, Int64)
60786078
@test Core.Compiler.return_type(gcondvarargs, Tuple{Vararg{Any}}) === Bool
6079+
6080+
# JuliaLang/julia#55627: argtypes check in `abstract_call_opaque_closure`
6081+
issue55627_some_method(x) = 2x
6082+
issue55627_make_oc() = Base.Experimental.@opaque (x::Int)->issue55627_some_method(x)
6083+
6084+
@test Base.infer_return_type() do
6085+
f = issue55627_make_oc()
6086+
return f(1), f()
6087+
end == Union{}
6088+
@test Base.infer_return_type((Vector{Int},)) do xs
6089+
f = issue55627_make_oc()
6090+
return f(1), f(xs...)
6091+
end == Tuple{Int,Int}

0 commit comments

Comments
 (0)