Skip to content

Commit 5864e43

Browse files
Fix tmerge for (partially) const types with undef fields (#43812)
When `tmerge` is applied to `Const`/`PartialStruct` and a field is `Const` in one of the types and `Union{}` (i.e. undef) in the other, the resulting field type must not be `Const` (as the resursively called `tmerge` produces). Fixes #43784.
1 parent 8ec5580 commit 5864e43

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

base/compiler/typelimits.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,12 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb))
414414
fields = Vector{Any}(undef, type_nfields)
415415
anyconst = false
416416
for i = 1:type_nfields
417-
ity = tmerge(getfield_tfunc(typea, Const(i)),
418-
getfield_tfunc(typeb, Const(i)))
417+
ai = getfield_tfunc(typea, Const(i))
418+
bi = getfield_tfunc(typeb, Const(i))
419+
ity = tmerge(ai, bi)
420+
if ai === Union{} || bi === Union{}
421+
ity = widenconst(ity)
422+
end
419423
fields[i] = ity
420424
anyconst |= has_nontrivial_const_info(ity)
421425
end

test/compiler/inference.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3989,3 +3989,23 @@ end |> only == Int
39893989
end
39903990
end |> only === Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedB}
39913991
end
3992+
3993+
# issue #43784
3994+
@testset "issue #43784" begin
3995+
init = Base.ImmutableDict{Any,Any}()
3996+
a = Const(init)
3997+
b = Core.PartialStruct(typeof(init), Any[Const(init), Any, Any])
3998+
c = Core.Compiler.tmerge(a, b)
3999+
@test (a, c)
4000+
@test (b, c)
4001+
4002+
@test @eval Module() begin
4003+
const ginit = Base.ImmutableDict{Any,Any}()
4004+
Base.return_types() do
4005+
g = ginit
4006+
while true
4007+
g = Base.ImmutableDict(g, 1=>2)
4008+
end
4009+
end |> only === Union{}
4010+
end
4011+
end

0 commit comments

Comments
 (0)