Skip to content

Commit a3a9182

Browse files
aviateskKristofferC
authored andcommitted
inference: fix #42090, make sure not to wrap Conditional in PartialStruct (#42091)
(cherry picked from commit 03e7b23)
1 parent 1f34cd3 commit a3a9182

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
14761476
anyconst = false
14771477
allconst = true
14781478
for i = 2:length(e.args)
1479-
at = abstract_eval_value(interp, e.args[i], vtypes, sv)
1479+
at = widenconditional(abstract_eval_value(interp, e.args[i], vtypes, sv))
14801480
if !anyconst
14811481
anyconst = has_nontrivial_const_info(at)
14821482
end

test/compiler/inference.jl

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,16 +1828,39 @@ end
18281828
return c, d # ::Tuple{Int,Int}
18291829
end == Any[Tuple{Int,Int}]
18301830

1831-
# shouldn't use the old constraint when the subject of condition has changed
1831+
# should invalidate old constraint when the subject of condition has changed
18321832
@test Base.return_types((Union{Nothing,Int},)) do a
1833-
b = a === nothing
1834-
c = b ? 0 : a # c::Int
1833+
cond = a === nothing
1834+
r1 = cond ? 0 : a # r1::Int
18351835
a = 0
1836-
d = b ? a : 1 # d::Int, not d::Union{Nothing,Int}
1837-
return c, d # ::Tuple{Int,Int}
1836+
r2 = cond ? a : 1 # r2::Int, not r2::Union{Nothing,Int}
1837+
return r1, r2 # ::Tuple{Int,Int}
18381838
end == Any[Tuple{Int,Int}]
18391839
end
18401840

1841+
# https://github.com/JuliaLang/julia/issues/42090#issuecomment-911824851
1842+
# `PartialStruct` shoudln't wrap `Conditional`
1843+
let M = Module()
1844+
@eval M begin
1845+
struct BePartialStruct
1846+
val::Int
1847+
cond
1848+
end
1849+
end
1850+
1851+
rt = @eval M begin
1852+
Base.return_types((Union{Nothing,Int},)) do a
1853+
cond = a === nothing
1854+
obj = $(Expr(:new, M.BePartialStruct, 42, :cond))
1855+
r1 = getfield(obj, :cond) ? 0 : a # r1::Union{Nothing,Int}, not r1::Int (because PartialStruct doesn't wrap Conditional)
1856+
a = $(gensym(:anyvar))::Any
1857+
r2 = getfield(obj, :cond) ? a : nothing # r2::Any, not r2::Const(nothing) (we don't need to worry about constrait invalidation here)
1858+
return r1, r2 # ::Tuple{Union{Nothing,Int},Any}
1859+
end |> only
1860+
end
1861+
@test rt == Tuple{Union{Nothing,Int},Any}
1862+
end
1863+
18411864
@testset "conditional constraint propagation from non-`Conditional` object" begin
18421865
@test Base.return_types((Bool,)) do b
18431866
if b

0 commit comments

Comments
 (0)