diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 65134bacc422f..8c8f868b2ed8b 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1498,20 +1498,26 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, (; fargs if isa(aty, Const) && isa(b, SlotNumber) if rt === Const(false) aty = Union{} + bty = widenconditional(bty) elseif rt === Const(true) bty = Union{} elseif bty isa Type && isdefined(typeof(aty.val), :instance) # can only widen a if it is a singleton bty = typesubtract(bty, typeof(aty.val), InferenceParams(interp).MAX_UNION_SPLITTING) + else + bty = widenconditional(bty) end return Conditional(b, aty, bty) end if isa(bty, Const) && isa(a, SlotNumber) if rt === Const(false) bty = Union{} + aty = widenconditional(aty) elseif rt === Const(true) aty = Union{} elseif aty isa Type && isdefined(typeof(bty.val), :instance) # same for b aty = typesubtract(aty, typeof(bty.val), InferenceParams(interp).MAX_UNION_SPLITTING) + else + aty = widenconditional(aty) end return Conditional(a, bty, aty) end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 77b74969b099b..972cc9f188edc 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2102,6 +2102,16 @@ let M = Module() @test rt == Tuple{Union{Nothing,Int},Any} end +# make sure we never form nested `Conditional` (https://github.com/JuliaLang/julia/issues/46207) +@test Base.return_types((Any,)) do a + c = isa(a, Integer) + 42 === c ? :a : "b" +end |> only === String +@test Base.return_types((Any,)) do a + c = isa(a, Integer) + c === 42 ? :a : "b" +end |> only === String + @testset "conditional constraint propagation from non-`Conditional` object" begin @test Base.return_types((Bool,)) do b if b