From 41b60ccef1d6e1307584fbe3c96a23ae90985bea Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 21 Jun 2015 16:21:24 -0500 Subject: [PATCH] WIP: unpack TypeVars before subtyping with Union (fixes #11803, fixes #11015) --- base/essentials.jl | 2 +- base/inference.jl | 6 +++--- src/jltypes.c | 35 ++++++++++++++++++----------------- test/core.jl | 2 ++ 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/base/essentials.jl b/base/essentials.jl index eb6127c13e30e..dbc7e0e900895 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -81,7 +81,7 @@ end isvarargtype(t::ANY) = isa(t,DataType)&&is((t::DataType).name,Vararg.name) isvatuple(t::DataType) = (n = length(t.parameters); n > 0 && isvarargtype(t.parameters[n])) -unwrapva(t::ANY) = isvarargtype(t) ? t.parameters[1] : t +unwrapva(t::ANY) = isa(t,TypeVar) ? unwrapva(t.ub) : (isvarargtype(t) ? t.parameters[1] : t) @generated function tuple_type_tail{T<:Tuple}(::Type{T}) if isvatuple(T) && length(T.parameters) == 1 diff --git a/base/inference.jl b/base/inference.jl index 2e9acbdaffa9b..7fd795d418a41 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -1120,12 +1120,12 @@ function type_too_complex(t::ANY, d) if d > MAX_TYPE_DEPTH return true end - if isa(t,Union) + if isa(t,TypeVar) + return type_too_complex(t.lb,d+1) || type_too_complex(t.ub,d+1) + elseif isa(t,Union) p = t.types elseif isa(t,DataType) p = t.parameters - elseif isa(t,TypeVar) - return type_too_complex(t.lb,d+1) || type_too_complex(t.ub,d+1) else return false end diff --git a/src/jltypes.c b/src/jltypes.c index 4e8b31c609a46..a964d64c8b3ea 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2358,6 +2358,24 @@ static int jl_subtype_le(jl_value_t *a, jl_value_t *b, int ta, int invariant) return 1; } + if (jl_is_typevar(a)) { + if (jl_is_typevar(b)) { + return + jl_subtype_le((jl_value_t*)((jl_tvar_t*)a)->ub, + (jl_value_t*)((jl_tvar_t*)b)->ub, 0, 0) && + jl_subtype_le((jl_value_t*)((jl_tvar_t*)b)->lb, + (jl_value_t*)((jl_tvar_t*)a)->lb, 0, 0); + } + if (invariant) { + return 0; + } + return jl_subtype_le((jl_value_t*)((jl_tvar_t*)a)->ub, b, 0, 0); + } + if (jl_is_typevar(b)) { + return jl_subtype_le(a, (jl_value_t*)((jl_tvar_t*)b)->ub, 0, 0) && + jl_subtype_le((jl_value_t*)((jl_tvar_t*)b)->lb, a, 0, 0); + } + size_t i; if (!ta && jl_is_uniontype(a)) { jl_svec_t *ap = ((jl_uniontype_t*)a)->types; @@ -2477,23 +2495,6 @@ static int jl_subtype_le(jl_value_t *a, jl_value_t *b, int ta, int invariant) return 0; } - if (jl_is_typevar(a)) { - if (jl_is_typevar(b)) { - return - jl_subtype_le((jl_value_t*)((jl_tvar_t*)a)->ub, - (jl_value_t*)((jl_tvar_t*)b)->ub, 0, 0) && - jl_subtype_le((jl_value_t*)((jl_tvar_t*)b)->lb, - (jl_value_t*)((jl_tvar_t*)a)->lb, 0, 0); - } - if (invariant) { - return 0; - } - return jl_subtype_le((jl_value_t*)((jl_tvar_t*)a)->ub, b, 0, 0); - } - if (jl_is_typevar(b)) { - return jl_subtype_le(a, (jl_value_t*)((jl_tvar_t*)b)->ub, 0, 0) && - jl_subtype_le((jl_value_t*)((jl_tvar_t*)b)->lb, a, 0, 0); - } if ((jl_datatype_t*)a == jl_any_type) return 0; return jl_egal(a, b); diff --git a/test/core.jl b/test/core.jl index 1c1855f218acf..1e3183b54c32f 100644 --- a/test/core.jl +++ b/test/core.jl @@ -30,6 +30,8 @@ isnot(x,y) = !is(x,y) @test !(Type{Bottom} <: Type{Int32}) @test !(Vector{Float64} <: Vector{Union{Float64,Float32}}) testintersect(Vector{Float64}, Vector{Union{Float64,Float32}}, Bottom) +@test TypeVar(:T,Int,true) <: Int +@test TypeVar(:T,Union(Int,Float64),true) <: Union(Int,Float64) @test !isa(Array,Type{Any}) @test Type{Complex} <: DataType