From 4e66eb0fdf9a888ab6e10377fb2e79811551e820 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 22 Jan 2015 17:58:30 -0500 Subject: [PATCH] juliatypes.jl: WIP on diagonal dispatch [ci skip] --- examples/juliatypes.jl | 49 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/examples/juliatypes.jl b/examples/juliatypes.jl index 4f51f7a769a60..a6945b01afbb7 100644 --- a/examples/juliatypes.jl +++ b/examples/juliatypes.jl @@ -155,6 +155,8 @@ type Bounds lb ub right::Bool + concrete::Bool + Bounds(l,u,r) = new(l,u,r,false) end type UnionState @@ -266,7 +268,7 @@ end function isconcrete(v::Var, env) b = env.vars[v] #return issub(b.ub, b.lb, env) - return isconcrete(b.ub, env) # ??? + return b.concrete || isconcrete(b.ub, env) # ??? end function isconcrete(t::UnionAllT, env) @@ -302,14 +304,15 @@ function issub(a::TagT, b::TagT, env) bp = b.params[bi] end if isa(bp,Var) && env.vars[bp].right - if !isconcrete(ap, env) - ap = Var(:_,BottomT,ap) - env.vars[ap] = Bounds(BottomT, ap.ub, false) + if !isconcrete(env.vars[bp].lb, env) + return false + end + env.vars[bp].concrete = true + if isa(ap, Var) + env.vars[ap].concrete = true end - !(issub(ap,bp,env) && issub(bp,ap,env)) && return false - else - !issub(ap, bp, env) && return false end + !issub(ap, bp, env) && return false end return (la==lb && va==vb) || (vb && (la >= (va ? lb : lb-1))) end @@ -353,6 +356,9 @@ function var_lt(b::Var, a::Union(Ty,Var), env) bb = env.vars[b] !bb.right && return issub(bb.ub, a, env) # check ∀b . b<:a !issub(bb.lb, a, env) && return false + if bb.concrete + !issub(a, bb.ub, env) && return false + end # for contravariance we would need to compute a meet here, but # because of invariance bb.ub ⊓ a == a here always. however for this # to work we need to compute issub(left,right) before issub(right,left), @@ -365,6 +371,9 @@ function var_gt(b::Var, a::Union(Ty,Var), env) bb = env.vars[b] !bb.right && return issub(a, bb.lb, env) # check ∀b . b>:a !issub(a, bb.ub, env) && return false + if bb.concrete + !issub(bb.lb, a, env) && return false + end bb.lb = join(bb.lb, a, env) return true end @@ -517,6 +526,32 @@ using Base.Test issub_strict(x,y) = issub(x,y) && !issub(y,x) +function test_diagonal() + @test !issub(Ty((Integer,Integer)), @UnionAll T tupletype(T,T)) + @test !issub(Ty((Integer,Int)), (@UnionAll T @UnionAll S<:T tupletype(T,S))) + @test !issub(Ty((Integer,Int)), (@UnionAll T @UnionAll T<:S<:T tupletype(T,S))) + + @test issub((@UnionAll R tupletype(R,R)), + (@UnionAll T @UnionAll S tupletype(T,S)) ) + @test issub((@UnionAll R tupletype(R,R)), + (@UnionAll T @UnionAll S<:T tupletype(T,S)) ) + @test issub((@UnionAll R tupletype(R,R)), + (@UnionAll T @UnionAll T<:S<:T tupletype(T,S)) ) + @test issub((@UnionAll R tupletype(R,R)), + (@UnionAll T @UnionAll S>:T tupletype(T,S)) ) + + @test !issub((@UnionAll T @UnionAll S tupletype(T,S)), + (@UnionAll R tupletype(R,R))) + + @test issub((@UnionAll T @UnionAll S<:T tupletype(T,S)), + (@UnionAll R tupletype(R,R))) + + @test issub((@UnionAll T @UnionAll T<:S<:T tupletype(T,S)), + (@UnionAll R tupletype(R,R))) + +end + + # level 1: no varags, union, UnionAll function test_1() @test issub_strict(Int, Integer)