From a223bc78cde36c71c72482814aeec742a6404d92 Mon Sep 17 00:00:00 2001 From: Jameson Nash <vtjnash@gmail.com> Date: Fri, 9 Jun 2017 16:39:46 -0400 Subject: [PATCH] address review comments --- base/inference.jl | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index 0d6deba34801a..26abc11077b36 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -753,27 +753,32 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool, vars::Vector{TypeVar}=TypeV return R end +# limit the complexity of type `t` to be simpler than the comparison type `compare` +# no new values may be introduced, so the parameter `source` encodes the set of all values already present function limit_type_size(t::ANY, compare::ANY, source::ANY) source = svec(unwrap_unionall(compare), unwrap_unionall(source)) source[1] === source[2] && (source = svec(source[1])) type_more_complex(t, compare, source, TUPLE_COMPLEXITY_LIMIT_DEPTH) || return t r = _limit_type_size(t, compare, source) - #@assert !isa(t, Type) || t <: r + @assert t <: r + #@assert r === _limit_type_size(r, t, source) # this monotonicity constraint is slightly stronger than actually required, + # since we only actually need to demonstrate that repeated application would reaches a fixed point, + #not that it is already at the fixed point return r end sym_isless(a::Symbol, b::Symbol) = ccall(:strcmp, Int32, (Ptr{UInt8}, Ptr{UInt8}), a, b) < 0 function type_more_complex(t::ANY, c::ANY, sources::SimpleVector, tupledepth::Int) - # detect cases where the comparison is already trivially true + # detect cases where the comparison is trivial if t === c return false elseif t === Union{} return false # Bottom is as simple as they come elseif isa(t, DataType) && isempty(t.parameters) return false # fastpath: unparameterized types are always finite - elseif tupledepth > 0 && isa(t, Type) && isa(c, Type) && c !== Union{} && c <: t - return false # t is already wider than the comparison + elseif tupledepth > 0 && isa(unwrap_unionall(t), DataType) && isa(c, Type) && c !== Union{} && c <: t + return false # t is already wider than the comparison in the type lattice elseif tupledepth > 0 && is_derived_type_from_any(unwrap_unionall(t), sources) return false # t isn't something new end @@ -828,7 +833,7 @@ function type_more_complex(t::ANY, c::ANY, sources::SimpleVector, tupledepth::In !tPi.abstract && !cPi.abstract && sym_isless(cPi.name.name, tPi.name.name) # allow collect on (anonymous) Generators to nest, provided that their functions are appropriately ordered - # TODO: is there a better way + # TODO: is there a better way? continue end end @@ -903,8 +908,8 @@ function _limit_type_size(t::ANY, c::ANY, sources::SimpleVector) # type vs. comp return t # easy case elseif isa(t, DataType) && isempty(t.parameters) return t # fast path: unparameterized are always simple - elseif isa(t, Type) && isa(c, Type) && c !== Union{} && c <: t - return t # t is already wider than the comparison + elseif isa(unwrap_unionall(t), DataType) && isa(c, Type) && c !== Union{} && c <: t + return t # t is already wider than the comparison in the type lattice elseif is_derived_type_from_any(unwrap_unionall(t), sources) return t # t isn't something new end @@ -966,7 +971,7 @@ function _limit_type_size(t::ANY, c::ANY, sources::SimpleVector) # type vs. comp Q[np] = tuple_tail_elem(Bottom, Any[ tP[i] for i in np:length(tP) ]) end for i = 1:np - Q[i] = _limit_type_size(Q[i], cP[i], sources) # TODO: apply type_more_complex here? + Q[i] = _limit_type_size(Q[i], cP[i], sources) end return Tuple{Q...} end @@ -978,7 +983,18 @@ function _limit_type_size(t::ANY, c::ANY, sources::SimpleVector) # type vs. comp is_derived_type_from_any(tt, sources) && return t end end - return t.name.wrapper + if isvarargtype(t) + # never replace Vararg with non-Vararg + return Vararg + end + widert = t.name.wrapper + if !(t <: widert) + # This can happen when a typevar has bounds too wide for its context, e.g. + # `Complex{T} where T` is not a subtype of `Complex`. In that case widen even + # faster to something safe to ensure the result is a supertype of the input. + return Any + end + return widert end return Any end