@@ -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}]
18381838end
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