-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
[ci skip]
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jakebolewski
Member
|
||
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)), | ||
This comment has been minimized.
Sorry, something went wrong.
jakebolewski
Member
|
||
(@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) | ||
|
It looks like the logic
a.concrete = false
is being used to mean two things at the same time, namely "a is not concrete" and "a is not yet proven to be concrete".The logical conflation shows up here because as
ap
orbp
is determined to beconcrete
, other typevars in the environment which haveap
orbp
as upper bounds are not set toconcrete = true
and thus the type environment is in an inconsistent state.In the example
issub(Tuple{T,S},Tuple{R,R})
is called. In this method callT
is determined to be concrete andS<:T
is in the type environment butS
is not set to concrete even thoughS
is only used in a covariant context in the tuple type(T, S)
. The type environment that results after this line is executed is therefore inconsistent with the covariant usage ofS
.