diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index a197731b62f32..06ac61781af1c 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -785,11 +785,13 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize rettype = code.rettype if isdefined(code, :rettype_const) rettype_const = code.rettype_const + # the second subtyping conditions are necessary to distinguish usual cases + # from rare cases when `Const` wrapped those extended lattice type objects if isa(rettype_const, Vector{Any}) && !(Vector{Any} <: rettype) return PartialStruct(rettype, rettype_const), mi - elseif rettype <: Core.OpaqueClosure && isa(rettype_const, PartialOpaque) + elseif isa(rettype_const, PartialOpaque) && rettype <: Core.OpaqueClosure return rettype_const, mi - elseif isa(rettype_const, InterConditional) + elseif isa(rettype_const, InterConditional) && !(InterConditional <: rettype) return rettype_const, mi else return Const(rettype_const), mi diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 84750a1d2748b..ba42785cb1d4f 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -1819,6 +1819,18 @@ end Meta.isexpr(x, :call) && return x # x::Expr return nothing end == Any[Union{Nothing,Expr}] + + # handle the edge case + let ts = @eval Module() begin + edgecase(_) = $(Core.Compiler.InterConditional(2, Int, Any)) + # create cache + Base.return_types(edgecase, (Any,)) + Base.return_types((Any,)) do x + edgecase(x) ? x : nothing # ::Any + end + end + @test ts == Any[Any] + end end @testset "branching on conditional object" begin