Skip to content

Commit

Permalink
improve precision of typeof_tfunc a bit (JuliaLang#31043)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson authored Feb 14, 2019
1 parent a03da73 commit bd07ef4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
41 changes: 35 additions & 6 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -409,22 +409,41 @@ add_tfunc(pointerref, 3, 3,
end, 4)
add_tfunc(pointerset, 4, 4, (@nospecialize(a), @nospecialize(v), @nospecialize(i), @nospecialize(align)) -> a, 5)

# more accurate typeof_tfunc for vararg tuples abstract only in length
function typeof_concrete_vararg(@nospecialize(t))
np = length(t.parameters)
for i = 1:np
p = t.parameters[i]
if i == np && isvarargtype(p)
pp = unwrap_unionall(p)
if isconcretetype(pp.parameters[1]) && pp.parameters[2] isa TypeVar
return rewrap_unionall(Type{Tuple{t.parameters[1:np-1]..., pp}}, p)
end
elseif !isconcretetype(p)
break
end
end
return nothing
end

function typeof_tfunc(@nospecialize(t))
isa(t, Const) && return Const(typeof(t.val))
t = widenconst(t)
if isType(t)
tp = t.parameters[1]
if issingletontype(tp)
return Const(typeof(tp))
else
return Type
end
elseif isa(t, DataType)
if isconcretetype(t) || isvarargtype(t)
if isconcretetype(t)
return Const(t)
elseif t === Any
return DataType
else
if t.name === Tuple.name
tt = typeof_concrete_vararg(t)
tt === nothing || return tt
end
return Type{<:t}
end
elseif isa(t, Union)
Expand All @@ -434,10 +453,20 @@ function typeof_tfunc(@nospecialize(t))
elseif isa(t, TypeVar) && !(Any <: t.ub)
return typeof_tfunc(t.ub)
elseif isa(t, UnionAll)
return rewrap_unionall(widenconst(typeof_tfunc(unwrap_unionall(t))), t)
else
return DataType # typeof(anything)::DataType
u = unwrap_unionall(t)
if isa(u, DataType) && !u.abstract
if u.name === Tuple.name
uu = typeof_concrete_vararg(u)
if uu !== nothing
return rewrap_unionall(uu, t)
end
else
return rewrap_unionall(Type{u}, t)
end
end
return rewrap_unionall(widenconst(typeof_tfunc(u)), t)
end
return DataType # typeof(anything)::DataType
end
add_tfunc(typeof, 1, 1, typeof_tfunc, 0)

Expand Down
8 changes: 8 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,14 @@ let PT = PartialTuple(Tuple{Int64,UInt64}, Any[Const(10, false), UInt64])
end
@test sizeof_nothrow(Const(Tuple)) === false

using Core.Compiler: typeof_tfunc
@test typeof_tfunc(Tuple{Vararg{Int}}) == Type{Tuple{Vararg{Int,N}}} where N
@test typeof_tfunc(Tuple{Any}) == Type{<:Tuple{Any}}
@test typeof_tfunc(Type{Array}) === DataType
@test typeof_tfunc(Type{<:Array}) === DataType
@test typeof_tfunc(Array{Int}) == Type{Array{Int,N}} where N
@test typeof_tfunc(AbstractArray{Int}) == Type{<:AbstractArray{Int,N}} where N

function f23024(::Type{T}, ::Int) where T
1 + 1
end
Expand Down

0 comments on commit bd07ef4

Please sign in to comment.