Skip to content

Commit

Permalink
small workaround checks against incorrect subtyping for kind types fo…
Browse files Browse the repository at this point in the history
…r isa_tfunc
  • Loading branch information
jrevels committed Jul 6, 2018
1 parent ae8e95f commit 4e60aa2
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
15 changes: 10 additions & 5 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,15 @@ add_tfunc(throw, 1, 1, (@nospecialize(x)) -> Bottom, 0)
# returns (type, isexact)
# if isexact is false, the actual runtime type may (will) be a subtype of t
function instanceof_tfunc(@nospecialize(t))
if t === Bottom || t === typeof(Bottom)
return Bottom, true
elseif isa(t, Const)
if isa(t, Const)
if isa(t.val, Type)
return t.val, true
end
return Bottom, true
end
t = widenconst(t)
if t === Bottom || t === typeof(Bottom) || typeintersect(t, Type) === Bottom
return Bottom, true
elseif isType(t)
tp = t.parameters[1]
return tp, !has_free_typevars(tp)
Expand Down Expand Up @@ -391,15 +394,17 @@ add_tfunc(isa, 2, 2,
if t === Bottom
return Const(false)
elseif v t
if isexact
if isexact && isnotbrokensubtype(v, t)
return Const(true)
end
elseif isa(v, Const) || isa(v, Conditional) || isdispatchelem(v)
# this tests for knowledge of a leaftype appearing on the LHS
# (ensuring the isa is precise)
return Const(false)
elseif isexact && typeintersect(v, t) === Bottom
if !iskindtype(v) #= subtyping currently intentionally answers this query incorrectly for kinds =#
# similar to `isnotbrokensubtype` check above, `typeintersect(v, t)`
# can't be trusted for kind types so we do an extra check here
if !iskindtype(v)
return Const(false)
end
end
Expand Down
8 changes: 7 additions & 1 deletion base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ function issingletontype(@nospecialize t)
return false
end

# Subtyping currently intentionally answers certain queries incorrectly for kind types. For
# some of these queries, this check can be used to somewhat protect against making incorrect
# decisions based on incorrect subtyping. Note that this check, itself, is broken for
# certain combinations of `a` and `b` where one/both isa/are `Union`/`UnionAll` type(s)s.
isnotbrokensubtype(a, b) = (!iskindtype(b) || !isType(a) || issingletontype(a.parameters[1]))

argtypes_to_type(argtypes::Array{Any,1}) = Tuple{anymap(widenconst, argtypes)...}

function isknownlength(t::DataType)
Expand All @@ -52,7 +58,7 @@ end
# return an upper-bound on type `a` with type `b` removed
# such that `return <: a` && `Union{return, b} == Union{a, b}`
function typesubtract(@nospecialize(a), @nospecialize(b))
if a <: b
if a <: b && isnotbrokensubtype(a, b)
return Bottom
end
if isa(a, Union)
Expand Down

0 comments on commit 4e60aa2

Please sign in to comment.