Skip to content

Commit a823309

Browse files
committed
Improve precision of tmeet for vararg PartialStruct
1 parent f7f46af commit a823309

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

base/compiler/typelimits.jl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -602,17 +602,24 @@ function tmeet(@nospecialize(v), @nospecialize(t))
602602
return Bottom
603603
end
604604
@assert widev <: Tuple
605-
new_fields = Vector{Any}(undef, length(v.fields))
606-
for i = 1:length(new_fields)
607-
if isa(v.fields[i], Core.TypeofVararg)
608-
new_fields[i] = v.fields[i]
609-
else
610-
new_fields[i] = tmeet(v.fields[i], widenconst(getfield_tfunc(t, Const(i))))
611-
if new_fields[i] === Bottom
612-
return Bottom
613-
end
605+
if isa(ti, DataType) && ti.name === Tuple.name
606+
num_fields = length(ti.parameters)
607+
isva = isvatuple(ti)
608+
else
609+
nfields_ti = nfields_tfunc(ti)
610+
isva = !isa(nfields_ti, Const)
611+
num_fields = isva ? length(v.fields) : (nfields_ti::Const).val
612+
end
613+
new_fields = Vector{Any}(undef, num_fields)
614+
for i = 1:num_fields
615+
new_fields[i] = tmeet(getfield_tfunc(v, Const(i)), widenconst(getfield_tfunc(ti, Const(i))))
616+
if new_fields[i] === Bottom
617+
return Bottom
614618
end
615619
end
620+
if isva && isvarargtype(v.fields[end])
621+
new_fields[end] = Vararg{new_fields[end]}
622+
end
616623
return tuple_tfunc(new_fields)
617624
elseif isa(v, Conditional)
618625
if !(Bool <: t)

test/compiler/inference.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3146,6 +3146,18 @@ function splat_lotta_unions()
31463146
end
31473147
@test Core.Compiler.return_type(splat_lotta_unions, Tuple{}) >: Tuple{Int,Int,Int}
31483148

3149+
# issue #38971 and related precision issues
3150+
f28971() = (1, [2,3]...)::Tuple{Int,Int,Int}
3151+
@test @inferred(f28971()) == (1, 2, 3)
3152+
g28971(::Type{T}) where {T} = (1, Number[2,3]...)::T
3153+
@test Base.return_types(g28971, Tuple{Type{Tuple{Vararg{Int}}}})[1] == Tuple{Int,Vararg{Int}}
3154+
@test Base.return_types(g28971, Tuple{Type{Tuple{Int,Vararg{Int}}}})[1] == Tuple{Int,Vararg{Int}}
3155+
@test Base.return_types(g28971, Tuple{Type{Tuple{Int,Int,Vararg{Int}}}})[1] == Tuple{Int,Int,Vararg{Int}}
3156+
@test Base.return_types(g28971, Tuple{Type{Union{Tuple{Int,Int,Int},Tuple{Vararg{Float64}}}}})[1] == Tuple{Int,Int,Int}
3157+
let T = Union{Tuple{Int,Int,Int},Tuple{Int,Vararg{Float64}}}
3158+
@test T <: Base.return_types(g28971, Tuple{Type{T}})[1] <: Tuple{Int,Vararg{Union{Int,Float64}}}
3159+
end
3160+
31493161
# Bare Core.Argument in IR
31503162
@eval f_bare_argument(x) = $(Core.Argument(2))
31513163
@test Base.return_types(f_bare_argument, (Int,))[1] == Int

0 commit comments

Comments
 (0)