From aeed68c25d2969033c47fd571f1bafb24184bb19 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Tue, 3 Sep 2024 01:14:43 +0900 Subject: [PATCH] inference: check argtype compatibility in `abstract_call_opaque_closure` - fixes JuliaLang/julia#55627 --- base/compiler/abstractinterpretation.jl | 13 +++++++++---- test/compiler/inference.jl | 13 +++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index f3fc4e0423173..f2d4327668137 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2334,11 +2334,16 @@ end function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::PartialOpaque, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, check::Bool=true) sig = argtypes_to_type(arginfo.argtypes) - result = abstract_call_method(interp, closure.source::Method, sig, Core.svec(), false, si, sv) - (; rt, edge, effects, volatile_inf_result) = result tt = closure.typ - sigT = (unwrap_unionall(tt)::DataType).parameters[1] - match = MethodMatch(sig, Core.svec(), closure.source, sig <: rewrap_unionall(sigT, tt)) + ocargsig = rewrap_unionall((unwrap_unionall(tt)::DataType).parameters[1], tt) + ocargsig′ = unwrap_unionall(ocargsig) + ocargsig′ isa DataType || return CallMeta(Any, Any, Effects(), NoCallInfo()) + ocsig = rewrap_unionall(Tuple{Tuple, ocargsig′.parameters...}, ocargsig) + hasintersect(sig, ocsig) || return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) + ocmethod = closure.source::Method + result = abstract_call_method(interp, ocmethod, sig, Core.svec(), false, si, sv) + (; rt, edge, effects, volatile_inf_result) = result + match = MethodMatch(sig, Core.svec(), ocmethod, sig <: ocsig) 𝕃ₚ = ipo_lattice(interp) ⊑ₚ = ⊑(𝕃ₚ) const_result = volatile_inf_result diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 485ee579abd52..7e1fea54830c9 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -6076,3 +6076,16 @@ end fcondvarargs(a, b, c, d) = isa(d, Int64) gcondvarargs(a, x...) = return fcondvarargs(a, x...) ? isa(a, Int64) : !isa(a, Int64) @test Core.Compiler.return_type(gcondvarargs, Tuple{Vararg{Any}}) === Bool + +# JuliaLang/julia#55627: argtypes check in `abstract_call_opaque_closure` +issue55627_some_method(x) = 2x +issue55627_make_oc() = Base.Experimental.@opaque (x::Int)->issue55627_some_method(x) + +@test Base.infer_return_type() do + f = issue55627_make_oc() + return f(1), f() +end == Union{} +@test Base.infer_return_type((Vector{Int},)) do xs + f = issue55627_make_oc() + return f(1), f(xs...) +end == Tuple{Int,Int}