Skip to content

Commit d2289e6

Browse files
authored
inference: correctly handle rare cases when Const wraps InterConditional (#42434)
Otherwise, in rare cases, we may see this sort of weird behavior: ```julia julia> @eval edgecase(_) = $(Core.Compiler.InterConditional(2, Int, Any)) edgecase (generic function with 1 method) julia> code_typed((Any,)) do x edgecase(x) ? x : nothing end 1-element Vector{Any}: CodeInfo( 1 ─ goto #3 if not $(QuoteNode(Core.InterConditional(2, Int64, Any))) 2 ─ return x 3 ─ return Main.nothing ) => Any julia> code_typed((Any,)) do x edgecase(x) ? x : nothing end 1-element Vector{Any}: CodeInfo( 1 ─ goto #3 if not $(QuoteNode(Core.InterConditional(2, Int64, Any))) 2 ─ %2 = π (x, Int64) └── return %2 3 ─ return Main.nothing ) => Union{Nothing, Int64} ```
1 parent 7f66828 commit d2289e6

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

base/compiler/typeinfer.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,11 +785,13 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
785785
rettype = code.rettype
786786
if isdefined(code, :rettype_const)
787787
rettype_const = code.rettype_const
788+
# the second subtyping conditions are necessary to distinguish usual cases
789+
# from rare cases when `Const` wrapped those extended lattice type objects
788790
if isa(rettype_const, Vector{Any}) && !(Vector{Any} <: rettype)
789791
return PartialStruct(rettype, rettype_const), mi
790-
elseif rettype <: Core.OpaqueClosure && isa(rettype_const, PartialOpaque)
792+
elseif isa(rettype_const, PartialOpaque) && rettype <: Core.OpaqueClosure
791793
return rettype_const, mi
792-
elseif isa(rettype_const, InterConditional)
794+
elseif isa(rettype_const, InterConditional) && !(InterConditional <: rettype)
793795
return rettype_const, mi
794796
else
795797
return Const(rettype_const), mi

test/compiler/inference.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,18 @@ end
18191819
Meta.isexpr(x, :call) && return x # x::Expr
18201820
return nothing
18211821
end == Any[Union{Nothing,Expr}]
1822+
1823+
# handle the edge case
1824+
let ts = @eval Module() begin
1825+
edgecase(_) = $(Core.Compiler.InterConditional(2, Int, Any))
1826+
# create cache
1827+
Base.return_types(edgecase, (Any,))
1828+
Base.return_types((Any,)) do x
1829+
edgecase(x) ? x : nothing # ::Any
1830+
end
1831+
end
1832+
@test ts == Any[Any]
1833+
end
18221834
end
18231835

18241836
@testset "branching on conditional object" begin

0 commit comments

Comments
 (0)