Skip to content

Commit

Permalink
fix #32699, more accurate apply_type_tfunc for NamedTuple
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Jun 19, 2020
1 parent d6d5208 commit 6e1c4b8
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
31 changes: 29 additions & 2 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1079,11 +1079,14 @@ function apply_type_tfunc(@nospecialize(headtypetype), @nospecialize args...)
if !istuple && !isa(headtype, UnionAll)
return Union{}
end
uw = unwrap_unionall(headtype)
isnamedtuple = isa(uw, DataType) && uw.name === _NAMEDTUPLE_NAME
uncertain = false
canconst = true
tparams = Any[]
outervars = Any[]
varnamectr = 1
ua = headtype
for i = 1:largs
ai = widenconditional(args[i])
if isType(ai)
Expand All @@ -1105,8 +1108,11 @@ function apply_type_tfunc(@nospecialize(headtypetype), @nospecialize args...)
# ai = rename_unionall(ai)
# unw = unwrap_unionall(ai)
#end
ub = ai <: Type ? instanceof_tfunc(ai)[1] : Any
if istuple
if i == largs
# in the last parameter of a Tuple type, if the upper bound is Any
# then this could be a Vararg type.
if i == largs && ub === Any
push!(tparams, Vararg)
# XXX
#elseif isT
Expand All @@ -1122,13 +1128,34 @@ function apply_type_tfunc(@nospecialize(headtypetype), @nospecialize args...)
# ai = ai.body
# end
else
# Is this the second parameter to a NamedTuple?
if isnamedtuple && isa(ua, UnionAll) && uw.parameters[2] === ua.var
# If the names are known, keep the upper bound (which we know is
# at most Tuple), but otherwise widen to Tuple.
# This is a widening heuristic to avoid keeping type information
# that's unlikely to be useful.
if uw.parameters[1] isa Tuple || (i == 2 && tparams[1] isa Tuple)
if ub >: Tuple
ub = Tuple
end
else
ub = Tuple
end
else
ub = Any
end
tvname = varnamectr <= length(_tvarnames) ? _tvarnames[varnamectr] : :_Z
varnamectr += 1
v = TypeVar(tvname)
v = TypeVar(tvname, ub)
push!(tparams, v)
push!(outervars, v)
end
end
if isa(ua, UnionAll)
ua = ua.body
else
ua = nothing
end
end
local appl
try
Expand Down
7 changes: 7 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2649,3 +2649,10 @@ end
f(n) = depth(n, 1)
end
@test Base.return_types(TestConstPropRecursion.f, (TestConstPropRecursion.Node,)) == Any[Int]

# issue #32699
f32699(a) = (id = a[1],).id
@test Base.return_types(f32699, (Vector{Union{Int,Missing}},)) == Any[Union{Int,Missing}]
g32699(a) = Tuple{a}
@test Base.return_types(g32699, (Type{<:Integer},))[1] == Type{<:Tuple{Any}}
@test Base.return_types(g32699, (Type,))[1] == Type{<:Tuple}

0 comments on commit 6e1c4b8

Please sign in to comment.