@@ -1350,14 +1350,14 @@ end
1350
1350
T = _fieldtype_tfunc (𝕃, o′, f, isconcretetype (o′))
1351
1351
T === Bottom && return Bottom
1352
1352
PT = Const (Pair)
1353
- return instanceof_tfunc (apply_type_tfunc (𝕃, PT, T, T), true )[1 ]
1353
+ return instanceof_tfunc (apply_type_tfunc (𝕃, Any[ PT, T, T] ), true )[1 ]
1354
1354
end
1355
1355
@nospecs function replacefield!_tfunc (𝕃:: AbstractLattice , o, f, x, v, success_order= Symbol, failure_order= Symbol)
1356
1356
o′ = widenconst (o)
1357
1357
T = _fieldtype_tfunc (𝕃, o′, f, isconcretetype (o′))
1358
1358
T === Bottom && return Bottom
1359
1359
PT = Const (ccall (:jl_apply_cmpswap_type , Any, (Any,), T) where T)
1360
- return instanceof_tfunc (apply_type_tfunc (𝕃, PT, T), true )[1 ]
1360
+ return instanceof_tfunc (apply_type_tfunc (𝕃, Any[ PT, T] ), true )[1 ]
1361
1361
end
1362
1362
@nospecs function setfieldonce!_tfunc (𝕃:: AbstractLattice , o, f, v, success_order= Symbol, failure_order= Symbol)
1363
1363
setfield!_tfunc (𝕃, o, f, v) === Bottom && return Bottom
@@ -1713,8 +1713,12 @@ end
1713
1713
const _tvarnames = Symbol[:_A , :_B , :_C , :_D , :_E , :_F , :_G , :_H , :_I , :_J , :_K , :_L , :_M ,
1714
1714
:_N , :_O , :_P , :_Q , :_R , :_S , :_T , :_U , :_V , :_W , :_X , :_Y , :_Z ]
1715
1715
1716
- # TODO : handle e.g. apply_type(T, R::Union{Type{Int32},Type{Float64}})
1717
- @nospecs function apply_type_tfunc (𝕃:: AbstractLattice , headtypetype, args... )
1716
+ function apply_type_tfunc (𝕃:: AbstractLattice , argtypes:: Vector{Any} ;
1717
+ max_union_splitting:: Int = InferenceParams (). max_union_splitting)
1718
+ if isempty (argtypes)
1719
+ return Bottom
1720
+ end
1721
+ headtypetype = argtypes[1 ]
1718
1722
headtypetype = widenslotwrapper (headtypetype)
1719
1723
if isa (headtypetype, Const)
1720
1724
headtype = headtypetype. val
@@ -1723,15 +1727,15 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1723
1727
else
1724
1728
return Any
1725
1729
end
1726
- if ! isempty (args) && isvarargtype (args[end ])
1730
+ largs = length (argtypes)
1731
+ if largs > 1 && isvarargtype (argtypes[end ])
1727
1732
return isvarargtype (headtype) ? TypeofVararg : Type
1728
1733
end
1729
- largs = length (args)
1730
1734
if headtype === Union
1731
- largs == 0 && return Const (Bottom)
1735
+ largs == 1 && return Const (Bottom)
1732
1736
hasnonType = false
1733
- for i = 1 : largs
1734
- ai = args [i]
1737
+ for i = 2 : largs
1738
+ ai = argtypes [i]
1735
1739
if isa (ai, Const)
1736
1740
if ! isa (ai. val, Type)
1737
1741
if isa (ai. val, TypeVar)
@@ -1750,14 +1754,14 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1750
1754
end
1751
1755
end
1752
1756
end
1753
- if largs == 1 # Union{T} --> T
1754
- return tmeet (widenconst (args[ 1 ]), Union{Type,TypeVar})
1757
+ if largs == 2 # Union{T} --> T
1758
+ return tmeet (widenconst (argtypes[ 2 ]), Union{Type,TypeVar})
1755
1759
end
1756
1760
hasnonType && return Type
1757
1761
ty = Union{}
1758
1762
allconst = true
1759
- for i = 1 : largs
1760
- ai = args [i]
1763
+ for i = 2 : largs
1764
+ ai = argtypes [i]
1761
1765
if isType (ai)
1762
1766
aty = ai. parameters[1 ]
1763
1767
allconst &= hasuniquerep (aty)
@@ -1768,6 +1772,18 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1768
1772
end
1769
1773
return allconst ? Const (ty) : Type{ty}
1770
1774
end
1775
+ if 1 < unionsplitcost (𝕃, argtypes) ≤ max_union_splitting
1776
+ rt = Bottom
1777
+ for split_argtypes = switchtupleunion (𝕃, argtypes)
1778
+ this_rt = widenconst (_apply_type_tfunc (𝕃, headtype, split_argtypes))
1779
+ rt = Union{rt, this_rt}
1780
+ end
1781
+ return rt
1782
+ end
1783
+ return _apply_type_tfunc (𝕃, headtype, argtypes)
1784
+ end
1785
+ @nospecs function _apply_type_tfunc (𝕃:: AbstractLattice , headtype, argtypes:: Vector{Any} )
1786
+ largs = length (argtypes)
1771
1787
istuple = headtype === Tuple
1772
1788
if ! istuple && ! isa (headtype, UnionAll) && ! isvarargtype (headtype)
1773
1789
return Union{}
@@ -1781,20 +1797,20 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1781
1797
# first push the tailing vars from headtype into outervars
1782
1798
outer_start, ua = 0 , headtype
1783
1799
while isa (ua, UnionAll)
1784
- if (outer_start += 1 ) > largs
1800
+ if (outer_start += 1 ) > largs - 1
1785
1801
push! (outervars, ua. var)
1786
1802
end
1787
1803
ua = ua. body
1788
1804
end
1789
- if largs > outer_start && isa (headtype, UnionAll) # e.g. !isvarargtype(ua) && !istuple
1805
+ if largs - 1 > outer_start && isa (headtype, UnionAll) # e.g. !isvarargtype(ua) && !istuple
1790
1806
return Bottom # too many arguments
1791
1807
end
1792
- outer_start = outer_start - largs + 1
1808
+ outer_start = outer_start - largs + 2
1793
1809
1794
1810
varnamectr = 1
1795
1811
ua = headtype
1796
- for i = 1 : largs
1797
- ai = widenslotwrapper (args [i])
1812
+ for i = 2 : largs
1813
+ ai = widenslotwrapper (argtypes [i])
1798
1814
if isType (ai)
1799
1815
aip1 = ai. parameters[1 ]
1800
1816
canconst &= ! has_free_typevars (aip1)
@@ -1868,7 +1884,7 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1868
1884
# If the names are known, keep the upper bound, but otherwise widen to Tuple.
1869
1885
# This is a widening heuristic to avoid keeping type information
1870
1886
# that's unlikely to be useful.
1871
- if ! (uw. parameters[1 ] isa Tuple || (i == 2 && tparams[1 ] isa Tuple))
1887
+ if ! (uw. parameters[1 ] isa Tuple || (i == 3 && tparams[1 ] isa Tuple))
1872
1888
ub = Any
1873
1889
end
1874
1890
else
@@ -1910,7 +1926,7 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1910
1926
# throwing errors.
1911
1927
appl = headtype
1912
1928
if isa (appl, UnionAll)
1913
- for _ = 1 : largs
1929
+ for _ = 2 : largs
1914
1930
appl = appl:: UnionAll
1915
1931
push! (outervars, appl. var)
1916
1932
appl = appl. body
@@ -1930,6 +1946,8 @@ const _tvarnames = Symbol[:_A, :_B, :_C, :_D, :_E, :_F, :_G, :_H, :_I, :_J, :_K,
1930
1946
end
1931
1947
return ans
1932
1948
end
1949
+ @nospecs apply_type_tfunc (𝕃:: AbstractLattice , headtypetype, args... ) =
1950
+ apply_type_tfunc (𝕃, Any[i == 0 ? headtypetype : args[i] for i in 0 : length (args)])
1933
1951
add_tfunc (apply_type, 1 , INT_INF, apply_type_tfunc, 10 )
1934
1952
1935
1953
# convert the dispatch tuple type argtype to the real (concrete) type of
@@ -2016,15 +2034,15 @@ end
2016
2034
T = _memoryref_elemtype (mem)
2017
2035
T === Bottom && return Bottom
2018
2036
PT = Const (Pair)
2019
- return instanceof_tfunc (apply_type_tfunc (𝕃, PT, T, T), true )[1 ]
2037
+ return instanceof_tfunc (apply_type_tfunc (𝕃, Any[ PT, T, T] ), true )[1 ]
2020
2038
end
2021
2039
@nospecs function memoryrefreplace!_tfunc (𝕃:: AbstractLattice , mem, x, v, success_order, failure_order, boundscheck)
2022
2040
memoryrefset!_tfunc (𝕃, mem, v, success_order, boundscheck) === Bottom && return Bottom
2023
2041
hasintersect (widenconst (failure_order), Symbol) || return Bottom
2024
2042
T = _memoryref_elemtype (mem)
2025
2043
T === Bottom && return Bottom
2026
2044
PT = Const (ccall (:jl_apply_cmpswap_type , Any, (Any,), T) where T)
2027
- return instanceof_tfunc (apply_type_tfunc (𝕃, PT, T), true )[1 ]
2045
+ return instanceof_tfunc (apply_type_tfunc (𝕃, Any[ PT, T] ), true )[1 ]
2028
2046
end
2029
2047
@nospecs function memoryrefsetonce!_tfunc (𝕃:: AbstractLattice , mem, v, success_order, failure_order, boundscheck)
2030
2048
memoryrefset!_tfunc (𝕃, mem, v, success_order, boundscheck) === Bottom && return Bottom
@@ -2666,6 +2684,8 @@ function builtin_tfunction(interp::AbstractInterpreter, @nospecialize(f), argtyp
2666
2684
end
2667
2685
end
2668
2686
return current_scope_tfunc (interp, sv)
2687
+ elseif f === Core. apply_type
2688
+ return apply_type_tfunc (𝕃ᵢ, argtypes; max_union_splitting= InferenceParams (interp). max_union_splitting)
2669
2689
end
2670
2690
fidx = find_tfunc (f)
2671
2691
if fidx === nothing
0 commit comments