diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 3e9f38c9ad98b..ff674f2d91894 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1240,8 +1240,12 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn const_prop_entry_heuristic(interp, result, sv) || return CallMeta(rt, InvokeCallInfo(match, nothing)) argtypes′ = argtypes[3:end] argtypes′[1] = ft - fargs′ = fargs[3:end] - fargs′[1] = fargs[1] + if fargs === nothing + fargs′ = nothing + else + fargs′ = fargs[3:end] + fargs′[1] = fargs[1] + end arginfo = ArgInfo(fargs′, argtypes′) const_prop_argument_heuristic(interp, arginfo, sv) || return CallMeta(rt, InvokeCallInfo(match, nothing)) # # typeintersect might have narrowed signature, but the accuracy gain doesn't seem worth the cost involved with the lattice comparisons diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 72791bfaa0a28..ce9a7fb13f318 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -3285,6 +3285,11 @@ function splat_lotta_unions() end @test Core.Compiler.return_type(splat_lotta_unions, Tuple{}) >: Tuple{Int,Int,Int} +# handle `fargs = nothing` edge cases +@test (code_typed(; optimize=false) do + Core.Compiler.return_type(invoke, Tuple{typeof(sin), Type{Tuple{Integer}}, Int}) +end; true) + # Bare Core.Argument in IR @eval f_bare_argument(x) = $(Core.Argument(2)) @test Base.return_types(f_bare_argument, (Int,))[1] == Int