Skip to content

Commit

Permalink
when widening tuple types in tmerge, only widen the complex parts
Browse files Browse the repository at this point in the history
  • Loading branch information
oscardssmith committed Aug 16, 2023
1 parent 0b190b3 commit fb7edce
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
25 changes: 13 additions & 12 deletions base/compiler/typelimits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -764,23 +764,24 @@ end
return u
end
# don't let the slow widening of Tuple cause the whole type to grow too fast
# Specifically widen Tuple{..., Union{lots of stuff}...} to Tuple{..., Any, ...}
for i in 1:length(types)
if typenames[i] === Tuple.name
widen = unwrap_unionall(types[i])
if isa(widen, DataType) && !isvatuple(widen)
widen = NTuple{length(widen.parameters), Any}
else
widen = Tuple
end
types[i] = widen
u = Union{types...}
if issimpleenoughtype(u)
return u
ti = types[i]
tip = (unwrap_unionall(types[i])::DataType).parameters
lt = length(tip)
p = Vector{Any}(undef, lt)
for j = 1:lt
ui = tip[j]
p[j] = (unioncomplexity(ui)==0) ? ui : isvarargtype(ui) ? Vararg : Any
end
break
types[i] = rewrap_unionall(Tuple{p...}, ti)
end
end
# finally, just return the widest possible type
u = Union{types...}
if issimpleenoughtype(u)
return u
end
return Any
end

Expand Down
15 changes: 15 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,21 @@ tmerge_test(Tuple{}, Tuple{Complex, Vararg{Union{ComplexF32, ComplexF64}}},
@test Core.Compiler.tmerge(Base.BitIntegerType, Union{}) === Base.BitIntegerType
@test Core.Compiler.tmerge(Union{}, Base.BitIntegerType) === Base.BitIntegerType
@test Core.Compiler.tmerge(Core.Compiler.fallback_ipo_lattice, Core.Compiler.InterConditional(1, Int, Union{}), Core.Compiler.InterConditional(2, String, Union{})) === Core.Compiler.Const(true)
# test issue behind https://github.com/JuliaLang/julia/issues/50458
@test Core.Compiler.tmerge(Nothing, Tuple{Base.BitInteger, Int}) == Union{Nothing, Tuple{Any, Int}}
@test Core.Compiler.tmerge(Nothing, Tuple{Union{Char, String, SubString{String}, Symbol}, Int}) == Union{Nothing, Tuple{Any, Int}}
@test Core.Compiler.tmerge(Nothing, Tuple{Integer, Int}) == Union{Nothing, Tuple{Integer, Int}}

# test that recursively more complicated types don't widen all the way to Any when there is a useful valid type upper bound
# Specificially test with base types of a trivial type, a simple union, a complicated union, and a tuple.
for T in (Nothing, Base.BitInteger, Union{Int, Int32, Int16, Int8}, Tuple{Int, Int})
Ta, Tb = T, T
for i in 1:10
Ta = Union{Tuple{Ta}, Nothing}
Tb = Core.Compiler.tmerge(Tuple{Tb}, Nothing)
@test Ta <: Tb <: Union{Nothing, Tuple}
end
end

struct SomethingBits
x::Base.BitIntegerType
Expand Down

0 comments on commit fb7edce

Please sign in to comment.