From 5a063ec94b5febd95bdba7c413d6c0d15c676d9a Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Tue, 20 Dec 2016 23:12:15 -0500 Subject: [PATCH] Handle non-const function in `return_types` special case Fix #19641 --- base/inference.jl | 30 +++++++++++++++++++----------- test/inference.jl | 6 ++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index 3d22339c54396..e96008dc192af 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -1095,22 +1095,23 @@ function abstract_apply(af::ANY, fargs, aargtypes::Vector{Any}, vtypes::VarTable end function pure_eval_call(f::ANY, argtypes::ANY, atype::ANY, vtypes::VarTable, sv::InferenceState) - for i = 2:length(argtypes) - a = argtypes[i] - if !(isa(a,Const) || isconstType(a,false)) - return false - end - end - if f === return_type && length(argtypes) == 3 # NOTE: only considering calls to return_type without InferenceParams arg tt = argtypes[3] - if isType(tt) + af = argtypes[2] + af_isconst = isa(af, Const) || isconstType(af, false) + if isconstType(tt, false) && + (af_isconst || (isleaftype(af) && + !(af <: Builtin) && !(af <: IntrinsicFunction))) af_argtype = tt.parameters[1] if af_argtype <: Tuple && isa(af_argtype, DataType) - af = argtypes[2] - rt = abstract_call(isa(af,Const) ? af.val : af.parameters[1], - (), Any[argtypes[2], af_argtype.parameters...], vtypes, sv) + argtypes_vec = Any[af, af_argtype.parameters...] + if af_isconst + rt = abstract_call(isa(af,Const) ? af.val : af.parameters[1], + (), argtypes_vec, vtypes, sv) + else + rt = abstract_call_gf_by_type(nothing, argtypes_to_type(argtypes_vec), sv) + end if isa(rt,Const) return Type{widenconst(rt)} elseif isleaftype(rt) || isleaftype(af_argtype) || rt === Bottom @@ -1122,6 +1123,13 @@ function pure_eval_call(f::ANY, argtypes::ANY, atype::ANY, vtypes::VarTable, sv: end end + for i = 2:length(argtypes) + a = argtypes[i] + if !(isa(a,Const) || isconstType(a,false)) + return false + end + end + min_valid = UInt[typemin(UInt)] max_valid = UInt[typemax(UInt)] meth = _methods_by_ftype(atype, 1, sv.params.world, min_valid, max_valid) diff --git a/test/inference.jl b/test/inference.jl index 5c8a5f83dba8b..91d7f78b293f1 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -465,3 +465,9 @@ function g19348(x) return a + b end test_inferred_static(@code_typed g19348((1, 2.0))) + +# Issue 19641 +foo19641() = let a = 1.0 + Core.Inference.return_type(x -> x + a, Tuple{Float64}) +end +@inferred foo19641()