Skip to content

Commit fdc3a16

Browse files
committed
allow external lattice to provide its own field-merge implementation
When merging `PartialStruct`, we are currently merging their fields a bit aggressively (#47307) in order to accelerate convergence. However, when `PartialStruct` wraps external lattice elements, this can be too aggressive since it does not use `tmerge(𝕃, fields...)` recursively and thus the external lattice elements are not merged as expected. This commit adds an additional lattice hook, `tmerge_field`, inside `tmerge(::PartialsLattice)` so that external lattice implementation can provide its own field-merge strategies.
1 parent eb57a77 commit fdc3a16

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

base/compiler/abstractlattice.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,23 @@ remaining mostly associative and commutative.
131131
"""
132132
function tmerge end
133133

134+
"""
135+
tmerge_field(𝕃::AbstractLattice, a, b) -> nothing or lattice element
136+
137+
Compute a lattice join of elements `a` and `b` over the lattice `𝕃`,
138+
where `a` and `b` are fields of `PartialStruct` or `Const`.
139+
This is an opt-in interface to allow external lattice implementation to provide its own
140+
field-merge strategy. If it returns `nothing`, `tmerge(::PartialsLattice, ...)`
141+
will use the default aggressive type merge implementation that does not use `tmerge`
142+
recursively to reach convergence.
143+
"""
144+
function tmerge_field end
145+
146+
function tmerge_field(𝕃::AbstractLattice, @nospecialize(a), @nospecialize(b))
147+
return tmerge_field(widenlattice(𝕃), a, b)
148+
end
149+
tmerge_field(::JLTypeLattice, @nospecialize(a), @nospecialize(b)) = nothing
150+
134151
"""
135152
⊑(𝕃::AbstractLattice, a, b)
136153

base/compiler/typelimits.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,12 @@ function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(ty
515515
tyi = ai
516516
elseif is_lattice_equal(lattice, bi, ft)
517517
tyi = bi
518+
elseif (tyi′ = tmerge_field(lattice, ai, bi); tyi′ !== nothing)
519+
# allow external lattice implementation to provide a custom field-merge strategy
520+
tyi = tyi′
518521
else
519-
# Otherwise choose between using the fieldtype or some other simple merged type.
522+
# Otherwise use the default aggressive field-merge implementation, and
523+
# choose between using the fieldtype or some other simple merged type.
520524
# The wrapper type never has restrictions on complexity,
521525
# so try to use that to refine the estimated type too.
522526
tni = _typename(widenconst(ai))

0 commit comments

Comments
 (0)