diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index 4552c4f815337..d1e08dd1e1676 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -676,7 +676,7 @@ end return tmerge(wl, typea, typeb) end -@nospecializeinfer function tmerge(::JLTypeLattice, @nospecialize(typea::Type), @nospecialize(typeb::Type)) +@nospecializeinfer function tmerge(lattice::JLTypeLattice, @nospecialize(typea::Type), @nospecialize(typeb::Type)) # it's always ok to form a Union of two concrete types act = isconcretetype(typea) bct = isconcretetype(typeb) @@ -687,8 +687,8 @@ end if (act || isType(typea)) && (bct || isType(typeb)) return Union{typea, typeb} end - typea <: typeb && return typeb - typeb <: typea && return typea + u = tmerge_fast_path(lattice, typea, typeb) + u === nothing || return u return tmerge_types_slow(typea, typeb) end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index c5eabae239f83..b04b7a40e2591 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -4584,6 +4584,19 @@ end g = Base.ImmutableDict(g, 1=>2) end end |> only === Union{} + + a = Val{Union{}} + a = Core.Compiler.tmerge(Union{a, Val{a}}, a) + @test a == Union{Val{Union{}}, Val{Val{Union{}}}} + a = Core.Compiler.tmerge(Union{a, Val{a}}, a) + @test a == Union{Val{Union{}}, Val{Val{Union{}}}, Val{Union{Val{Union{}}, Val{Val{Union{}}}}}} + a = Core.Compiler.tmerge(Union{a, Val{a}}, a) + @test a == Val + + a = Val{Union{}} + a = Core.Compiler.tmerge(Core.Compiler.JLTypeLattice(), Val{<:a}, a) + @test_broken a != Val{<:Val{Union{}}} + @test_broken a == Val{<:Val} || a == Val end # Test that a function-wise `@max_methods` works as expected