diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 1574bd1092ff4..421cdb15edfdd 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -639,11 +639,33 @@ function pure_eval_call(@nospecialize(f), argtypes::Vector{Any}, @nospecialize(a end end +function argtype_by_index(argtypes::Vector{Any}, i::Int) + n = length(argtypes) + if isvarargtype(argtypes[n]) + return i >= n ? unwrapva(argtypes[n]) : argtypes[i] + else + return i > n ? Bottom : argtypes[i] + end +end + +function argtype_tail(argtypes::Vector{Any}, i::Int) + n = length(argtypes) + if isvarargtype(argtypes[n]) && i > n + i = n + end + return argtypes[i:n] +end + function abstract_call(@nospecialize(f), fargs::Union{Nothing,Vector{Any}}, argtypes::Vector{Any}, vtypes::VarTable, sv::InferenceState, max_methods = sv.params.MAX_METHODS) if f === _apply - return abstract_apply(nothing, argtypes[2], argtypes[3:end], vtypes, sv, max_methods) + ft = argtype_by_index(argtypes, 2) + ft === Bottom && return Bottom + return abstract_apply(nothing, ft, argtype_tail(argtypes, 3), vtypes, sv, max_methods) elseif f === _apply_iterate - return abstract_apply(argtypes[2], argtypes[3], argtypes[4:end], vtypes, sv, max_methods) + itft = argtype_by_index(argtypes, 2) + ft = argtype_by_index(argtypes, 3) + (itft === Bottom || ft === Bottom) && return Bottom + return abstract_apply(itft, ft, argtype_tail(argtypes, 4), vtypes, sv, max_methods) end la = length(argtypes) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index cbfb70b1cf156..bd96133892872 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -885,6 +885,9 @@ function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::Params) while sig.f === Core._apply || sig.f === Core._apply_iterate arg_start = sig.f === Core._apply ? 2 : 3 atypes = sig.atypes + if arg_start > length(atypes) + return nothing + end # Try to figure out the signature of the function being called # and if rewrite_apply_exprargs can deal with this form for i = (arg_start + 1):length(atypes) diff --git a/src/builtins.c b/src/builtins.c index f778b32a125be..13c0353aa6b0d 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -476,7 +476,6 @@ static jl_function_t *jl_iterate_func JL_GLOBALLY_ROOTED; static jl_value_t *do_apply(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_value_t *iterate) { - JL_NARGSV(apply, 1); jl_function_t *f = args[0]; if (nargs == 2) { // some common simple cases @@ -634,11 +633,13 @@ static jl_value_t *do_apply(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl JL_CALLABLE(jl_f__apply_iterate) { + JL_NARGSV(_apply_iterate, 2); return do_apply(F, args+1, nargs-1, args[0]); } JL_CALLABLE(jl_f__apply) { + JL_NARGSV(_apply, 1); return do_apply(F, args, nargs, NULL); } diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 9742f2d3c26d0..a69d7c776608b 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2464,3 +2464,21 @@ let N = TypeVar(:N) Core.Compiler.PartialTypeVar(N, true, true), Core.Compiler.Const(Any)], Type{Tuple{Vararg{Any,N}}}) end + +# issue #33768 +function f33768() + Core._apply() +end +function g33768() + a = Any[iterate, tuple, (1,)] + Core._apply_iterate(a...) +end +function h33768() + Core._apply_iterate() +end +@test_throws ArgumentError f33768() +@test Base.return_types(f33768, ()) == Any[Union{}] +@test g33768() === (1,) +@test Base.return_types(g33768, ()) == Any[Any] +@test_throws ArgumentError h33768() +@test Base.return_types(h33768, ()) == Any[Union{}]