Skip to content

Commit

Permalink
lattice: Don't forget to pass down lattice in Conditional tmerge
Browse files Browse the repository at this point in the history
Also add some extra cases that before were taken care of by the
tmerge_fast_path at the entry to the tmerge code. I briefly
considered splitting an extra slow path function to avoid the
one `===` in the ConstsLattice, but in the non-equality case
that check should be quite fast, so it didn't seem worth it.
  • Loading branch information
Keno committed Dec 25, 2022
1 parent ea13810 commit c8df7cb
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions base/compiler/typelimits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ function tmerge(lattice::ConditionalsLattice, @nospecialize(typea), @nospecializ
end
if isa(typea, Conditional) && isa(typeb, Conditional)
if is_same_conditionals(typea, typeb)
thentype = tmerge(typea.thentype, typeb.thentype)
elsetype = tmerge(typea.elsetype, typeb.elsetype)
thentype = tmerge(widenlattice(lattice), typea.thentype, typeb.thentype)
elsetype = tmerge(widenlattice(lattice), typea.elsetype, typeb.elsetype)
if thentype !== elsetype
return Conditional(typea.slot, thentype, elsetype)
end
Expand Down Expand Up @@ -464,8 +464,8 @@ function tmerge(lattice::InterConditionalsLattice, @nospecialize(typea), @nospec
end
if isa(typea, InterConditional) && isa(typeb, InterConditional)
if is_same_conditionals(typea, typeb)
thentype = tmerge(typea.thentype, typeb.thentype)
elsetype = tmerge(typea.elsetype, typeb.elsetype)
thentype = tmerge(widenlattice(lattice), typea.thentype, typeb.thentype)
elsetype = tmerge(widenlattice(lattice), typea.elsetype, typeb.elsetype)
if thentype !== elsetype
return InterConditional(typea.slot, thentype, elsetype)
end
Expand Down Expand Up @@ -506,6 +506,9 @@ function tmerge_partial_struct(lattice::PartialsLattice, @nospecialize(typea), @
for i = 1:type_nfields
ai = getfield_tfunc(lattice, typea, Const(i))
bi = getfield_tfunc(lattice, typeb, Const(i))
# N.B.: We're assuming here that !isType(aty), because that case
# only arises when typea === typeb, which should have been caught
# before calling this.
ft = fieldtype(aty, i)
if is_lattice_equal(lattice, ai, bi) || is_lattice_equal(lattice, ai, ft)
# Since ai===bi, the given type has no restrictions on complexity.
Expand Down Expand Up @@ -551,6 +554,7 @@ function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(ty
acp = aps || isa(typea, Const)
bcp = bps || isa(typeb, Const)
if acp && bcp
typea === typeb && return typea
psrt = tmerge_partial_struct(lattice, typea, typeb)
psrt !== nothing && return psrt
end
Expand Down Expand Up @@ -586,17 +590,18 @@ function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(ty
return tmerge(wl, typea, typeb)
end


function tmerge(lattice::ConstsLattice, @nospecialize(typea), @nospecialize(typeb))
# the equality of the constants can be checked here, but the equivalent check is usually
# done by `tmerge_fast_path` at earlier lattice stage
typea === typeb && return typea
wl = widenlattice(lattice)
(isa(typea, Const) || isa(typea, PartialTypeVar)) && (typea = widenlattice(wl, typea))
(isa(typeb, Const) || isa(typeb, PartialTypeVar)) && (typeb = widenlattice(wl, typeb))
return tmerge(wl, typea, typeb)
end

function tmerge(::JLTypeLattice, @nospecialize(typea::Type), @nospecialize(typeb::Type))
typea == typeb && return typea
typea <: typeb && return typeb
typeb <: typea && return typea
# it's always ok to form a Union of two concrete types
if (isconcretetype(typea) || isType(typea)) && (isconcretetype(typeb) || isType(typeb))
return Union{typea, typeb}
Expand Down

0 comments on commit c8df7cb

Please sign in to comment.