Skip to content

Commit 03e7b23

Browse files
authored
inference: fix #42090, make sure not to wrap Conditional in PartialStruct (#42091)
1 parent bada80c commit 03e7b23

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
@@ -1536,7 +1536,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
15361536
anyconst = false
15371537
allconst = true
15381538
for i = 2:length(e.args)
1539-
at = abstract_eval_value(interp, e.args[i], vtypes, sv)
1539+
at = widenconditional(abstract_eval_value(interp, e.args[i], vtypes, sv))
15401540
if !anyconst
15411541
anyconst = has_nontrivial_const_info(at)
15421542
end

test/compiler/inference.jl

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

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

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

0 commit comments

Comments
 (0)