@@ -3755,3 +3755,63 @@ end |> only == Tuple{Int,Int}
3755
3755
s2 = Some {Any} (s1)
3756
3756
s2. value. value
3757
3757
end |> only == Int
3758
+
3759
+ # issue #42986
3760
+ @testset " narrow down `Union` using `isdefined` checks" begin
3761
+ # basic functionality
3762
+ @test Base. return_types ((Union{Nothing,Core. CodeInstance},)) do x
3763
+ if isdefined (x, :inferred )
3764
+ return x
3765
+ else
3766
+ throw (" invalid" )
3767
+ end
3768
+ end |> only === Core. CodeInstance
3769
+
3770
+ @test Base. return_types ((Union{Nothing,Core. CodeInstance},)) do x
3771
+ if isdefined (x, :not_exist )
3772
+ return x
3773
+ else
3774
+ throw (" invalid" )
3775
+ end
3776
+ end |> only === Union{}
3777
+
3778
+ # even when isdefined is malformed, we can filter out types with no fields
3779
+ @test Base. return_types ((Union{Nothing, Core. CodeInstance},)) do x
3780
+ if isdefined (x, 5 )
3781
+ return x
3782
+ else
3783
+ throw (" invalid" )
3784
+ end
3785
+ end |> only === Core. CodeInstance
3786
+
3787
+ struct UnionNarrowingByIsdefinedA; x; end
3788
+ struct UnionNarrowingByIsdefinedB; x; end
3789
+ struct UnionNarrowingByIsdefinedC; x; end
3790
+
3791
+ # > 2 types in the union
3792
+ @test Base. return_types ((Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedB, UnionNarrowingByIsdefinedC},)) do x
3793
+ if isdefined (x, :x )
3794
+ return x
3795
+ else
3796
+ throw (" invalid" )
3797
+ end
3798
+ end |> only === Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedB, UnionNarrowingByIsdefinedC}
3799
+
3800
+ # > 2 types in the union and some aren't defined
3801
+ @test Base. return_types ((Union{UnionNarrowingByIsdefinedA, Core. CodeInstance, UnionNarrowingByIsdefinedC},)) do x
3802
+ if isdefined (x, :x )
3803
+ return x
3804
+ else
3805
+ throw (" invalid" )
3806
+ end
3807
+ end |> only === Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedC}
3808
+
3809
+ # should respect `Const` information still
3810
+ @test Base. return_types ((Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedB},)) do x
3811
+ if isdefined (x, :x )
3812
+ return x
3813
+ else
3814
+ return nothing # dead branch
3815
+ end
3816
+ end |> only === Union{UnionNarrowingByIsdefinedA, UnionNarrowingByIsdefinedB}
3817
+ end
0 commit comments