Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inference: handle Vararg in abstract_call_unionall for argtypes computed by abstract_apply #51393

Merged
merged 1 commit into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1858,7 +1858,12 @@ function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{An
a2 = argtypes[2]
a3 = argtypes[3]
⊑ᵢ = ⊑(typeinf_lattice(interp))
nothrow = a2 ⊑ᵢ TypeVar && (a3 ⊑ᵢ Type || a3 ⊑ᵢ TypeVar)
if isvarargtype(a3)
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The length(argtypes) check is not correct either if you have varargs

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but what we are trying to model here is call to the UnionAll(tv, t) method, which just throws MethodError when length(argtypes) ≠ 3 at runtime. So this is fine as far as we model nothrow correctly.

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you have Vararg, you don’t know if length!=3, so you don’t know that if it throws an error or not

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can't concluded that the rt is Bottom if either of the first two argtypes is Vararg, we should fix that.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right... I will work on it.

a3 = unwrapva(a3)
nothrow = false
else
nothrow = a2 ⊑ᵢ TypeVar && (a3 ⊑ᵢ Type || a3 ⊑ᵢ TypeVar)
end
if isa(a3, Const)
body = a3.val
elseif isType(a3)
Expand Down Expand Up @@ -2253,7 +2258,6 @@ function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::
return Any
end


function abstract_eval_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::Union{VarTable,Nothing}, sv::AbsIntState)
if isa(e, Expr)
return abstract_eval_value_expr(interp, e, vtypes, sv)
Expand Down
7 changes: 6 additions & 1 deletion test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Core.Compiler: Const, Conditional, ⊑, ReturnNode, GotoIfNot
isdispatchelem(@nospecialize x) = !isa(x, Type) || Core.Compiler.isdispatchelem(x)

using Random, Core.IR
using InteractiveUtils: code_llvm
using InteractiveUtils

include("irutils.jl")

Expand Down Expand Up @@ -5230,3 +5230,8 @@ end |> only == Val{false}
@test Base.return_types((Bool,)) do b
Val(Core.Intrinsics.or_int(true, b))
end |> only == Val{true}

# https://github.com/JuliaLang/julia/issues/51310
@test code_typed() do
b{c} = d...
end |> only |> first isa Core.CodeInfo