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