Skip to content

Commit 4e13e0e

Browse files
authored
inference: fix lattice for unusual InterConditional return and Const Bool representations (#57080)
Fixes #54886 Rule introduced by 55cee67
1 parent 7a1a6f3 commit 4e13e0e

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

Compiler/src/abstractinterpretation.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3785,14 +3785,23 @@ function update_bestguess!(interp::AbstractInterpreter, frame::InferenceState,
37853785
slottypes = frame.slottypes
37863786
rt = widenreturn(rt, BestguessInfo(interp, bestguess, nargs, slottypes, currstate))
37873787
# narrow representation of bestguess slightly to prepare for tmerge with rt
3788-
if rt isa InterConditional && bestguess isa Const
3788+
if rt isa InterConditional && bestguess isa Const && bestguess.val isa Bool
37893789
slot_id = rt.slot
37903790
old_id_type = widenconditional(slottypes[slot_id])
37913791
if bestguess.val === true && rt.elsetype !== Bottom
37923792
bestguess = InterConditional(slot_id, old_id_type, Bottom)
37933793
elseif bestguess.val === false && rt.thentype !== Bottom
37943794
bestguess = InterConditional(slot_id, Bottom, old_id_type)
37953795
end
3796+
# or narrow representation of rt slightly to prepare for tmerge with bestguess
3797+
elseif bestguess isa InterConditional && rt isa Const && rt.val isa Bool
3798+
slot_id = bestguess.slot
3799+
old_id_type = widenconditional(slottypes[slot_id])
3800+
if rt.val === true && bestguess.elsetype !== Bottom
3801+
rt = InterConditional(slot_id, old_id_type, Bottom)
3802+
elseif rt.val === false && bestguess.thentype !== Bottom
3803+
rt = InterConditional(slot_id, Bottom, old_id_type)
3804+
end
37963805
end
37973806
# copy limitations to return value
37983807
if !isempty(frame.pclimitations)

Compiler/src/typelattice.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,13 @@ end
395395
end
396396
a = Bool
397397
elseif isa(b, ConditionalT)
398+
if isa(a, Const) && isa(a.val, Bool)
399+
if (a.val === true && b.thentype === Any && b.elsetype === Bottom) ||
400+
(a.val === false && b.elsetype === Any && b.thentype === Bottom)
401+
# this Conditional contains distinctly no lattice information, and is simply an alternative representation of the Const Bool used for internal tracking purposes
402+
return true
403+
end
404+
end
398405
return false
399406
end
400407
return (widenlattice(lattice), a, b)

Compiler/test/inference.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,6 +2734,26 @@ vacond(cnd, va...) = cnd ? va : 0
27342734
vacond(isa(x, Tuple{Int,Int}), x, x)
27352735
end |> only == Union{Int,Tuple{Any,Any}}
27362736

2737+
let A = Core.Const(true)
2738+
B = Core.InterConditional(2, Tuple, Union{})
2739+
C = Core.InterConditional(2, Any, Union{})
2740+
L = ipo_lattice(Compiler.NativeInterpreter())
2741+
@test !(L, A, B)
2742+
@test (L, B, A)
2743+
@test tmerge(L, A, B) == C
2744+
@test (L, A, C)
2745+
end
2746+
function tail_is_ntuple((@nospecialize t::Tuple))
2747+
if unknown
2748+
t isa Tuple
2749+
else
2750+
tail_is_ntuple(t)
2751+
end
2752+
end
2753+
tail_is_ntuple_val((@nospecialize t::Tuple)) = Val(tail_is_ntuple(t))
2754+
@test Base.return_types(tail_is_ntuple, (Tuple,)) |> only === Bool
2755+
@test Base.return_types(tail_is_ntuple_val, (Tuple,)) |> only === Val{true}
2756+
27372757
# https://github.com/JuliaLang/julia/issues/47435
27382758
is_closed_ex(e::InvalidStateException) = true
27392759
is_closed_ex(e) = false

0 commit comments

Comments
 (0)