Skip to content

Commit

Permalink
Fix tmerge for (partially) const types with undef fields (JuliaLang…
Browse files Browse the repository at this point in the history
…#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 JuliaLang#43784.
  • Loading branch information
martinholters authored and LilithHafner committed Feb 22, 2022
1 parent e229b89 commit 8082a4b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
8 changes: 6 additions & 2 deletions base/compiler/typelimits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,12 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb))
fields = Vector{Any}(undef, type_nfields)
anyconst = false
for i = 1:type_nfields
ity = tmerge(getfield_tfunc(typea, Const(i)),
getfield_tfunc(typeb, Const(i)))
ai = getfield_tfunc(typea, Const(i))
bi = getfield_tfunc(typeb, Const(i))
ity = tmerge(ai, bi)
if ai === Union{} || bi === Union{}
ity = widenconst(ity)
end
fields[i] = ity
anyconst |= has_nontrivial_const_info(ity)
end
Expand Down
20 changes: 20 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3989,3 +3989,23 @@ end |> only == Int
end
end |> only === Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedB}
end

# issue #43784
@testset "issue #43784" begin
init = Base.ImmutableDict{Any,Any}()
a = Const(init)
b = Core.PartialStruct(typeof(init), Any[Const(init), Any, Any])
c = Core.Compiler.tmerge(a, b)
@test (a, c)
@test (b, c)

@test @eval Module() begin
const ginit = Base.ImmutableDict{Any,Any}()
Base.return_types() do
g = ginit
while true
g = Base.ImmutableDict(g, 1=>2)
end
end |> only === Union{}
end
end

0 comments on commit 8082a4b

Please sign in to comment.