@@ -82,6 +82,13 @@ type Conditional
82
82
end
83
83
end
84
84
85
+ immutable PartialTypeVar
86
+ tv:: TypeVar
87
+ lb_certain:: Bool
88
+ ub_certain:: Bool
89
+ PartialTypeVar (tv:: TypeVar , lb_certain:: ANY , ub_certain:: ANY ) = new (tv, lb_certain, ub_certain)
90
+ end
91
+
85
92
function rewrap (t:: ANY , u:: ANY )
86
93
isa (t, Const) && return t
87
94
isa (t, Conditional) && return t
@@ -678,6 +685,7 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool=true, var::Union{Void,TypeVa
678
685
return (cov && ! stillcov) ? UnionAll (var, R) : R
679
686
end
680
687
688
+ const DataType_name_fieldindex = fieldindex (DataType, :name )
681
689
const DataType_parameters_fieldindex = fieldindex (DataType, :parameters )
682
690
const DataType_types_fieldindex = fieldindex (DataType, :types )
683
691
const DataType_super_fieldindex = fieldindex (DataType, :super )
@@ -713,7 +721,8 @@ function getfield_tfunc(s00::ANY, name)
713
721
if isa (sv, Module) && isa (nv, Symbol)
714
722
return abstract_eval_global (sv, nv)
715
723
end
716
- if (isa (sv, DataType) || isimmutable (sv)) && isdefined (sv, nv)
724
+ if (isa (sv, DataType) || isa (sv, SimpleVector) || isa (sv, TypeName)
725
+ || isimmutable (sv)) && isdefined (sv, nv)
717
726
return abstract_eval_constant (getfield (sv, nv))
718
727
end
719
728
end
@@ -774,7 +783,8 @@ function getfield_tfunc(s00::ANY, name)
774
783
sp = nothing
775
784
end
776
785
if (sp != = nothing &&
777
- (fld == DataType_parameters_fieldindex ||
786
+ (fld == DataType_name_fieldindex ||
787
+ fld == DataType_parameters_fieldindex ||
778
788
fld == DataType_types_fieldindex ||
779
789
fld == DataType_super_fieldindex))
780
790
return Const (getfield (sp, fld))
@@ -905,15 +915,19 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
905
915
return Any
906
916
end
907
917
uncertain = false
918
+ uncertain_typevar = false
908
919
tparams = Any[]
909
920
outervars = Any[]
910
921
for i = 1 : largs
911
922
ai = args[i]
912
923
if isType (ai)
913
924
aip1 = ai. parameters[1 ]
914
925
push! (tparams, aip1)
915
- elseif isa (ai, Const) && (isa (ai. val, Type) || valid_tparam (ai. val))
926
+ elseif isa (ai, Const) && (isa (ai. val, Type) || isa (ai . val, TypeVar) || valid_tparam (ai. val))
916
927
push! (tparams, ai. val)
928
+ elseif isa (ai, PartialTypeVar)
929
+ uncertain_typevar = true
930
+ push! (tparams, ai. tv)
917
931
else
918
932
# TODO : return `Bottom` for trying to apply a non-UnionAll
919
933
uncertain = true
@@ -956,7 +970,8 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
956
970
# doesn't match, which could happen if a type estimate is too coarse
957
971
return Type{_} where _<: headtype
958
972
end
959
- ! uncertain && return Const (appl)
973
+ ! uncertain && ! uncertain_typevar && return Const (appl)
974
+ ! uncertain && return Type{appl}
960
975
if isvarargtype (headtype)
961
976
return Type
962
977
end
@@ -1476,6 +1491,25 @@ function Pair_name()
1476
1491
return _Pair_name
1477
1492
end
1478
1493
1494
+ _typename (a) = Union{}
1495
+ _typename (a:: Vararg ) = Any
1496
+ _typename (a:: TypeVar ) = Any
1497
+ _typename (a:: DataType ) = Const (a. name)
1498
+ function _typename (a:: Union )
1499
+ ta = _typename (a. a)
1500
+ tb = _typename (a. b)
1501
+ ta == tb ? tb : (ta === Any || tb == Any) ? Any : Union{}
1502
+ end
1503
+ _typename (union:: UnionAll ) = typename (union. body)
1504
+ function typename_static (t)
1505
+ # N.B.: typename maps type equivalence classes to a single value
1506
+ if isa (t, Const) || isType (t)
1507
+ return _typename (isa (t, Const) ? t. val : t. parameters[1 ])
1508
+ else
1509
+ return Any
1510
+ end
1511
+ end
1512
+
1479
1513
function abstract_call (f:: ANY , fargs:: Union{Tuple{},Vector{Any}} , argtypes:: Vector{Any} , vtypes:: VarTable , sv:: InferenceState )
1480
1514
if f === _apply
1481
1515
length (fargs) > 1 || return Any
@@ -1557,19 +1591,63 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
1557
1591
end
1558
1592
end
1559
1593
return Any
1560
- elseif f === UnionAll
1561
- if length (fargs) == 3 && isa (argtypes[2 ], Const)
1562
- tv = argtypes[2 ]. val
1563
- if isa (tv, TypeVar)
1594
+ elseif f === TypeVar
1595
+ lb = Union{}
1596
+ ub = Any
1597
+ ub_certain = lb_certain = true
1598
+ if length (fargs) >= 2 && isa (argtypes[2 ], Const)
1599
+ nv = argtypes[2 ]. val
1600
+ ubidx = 3
1601
+ if length (fargs) >= 4
1602
+ ubidx = 4
1564
1603
if isa (argtypes[3 ], Const)
1565
- body = argtypes[3 ]. val
1604
+ lb = argtypes[3 ]. val
1566
1605
elseif isType (argtypes[3 ])
1567
- body = argtypes[3 ]. parameters[1 ]
1606
+ lb = argtypes[3 ]. parameters[1 ]
1607
+ lb_certain = false
1568
1608
else
1569
- return Any
1609
+ return TypeVar
1610
+ end
1611
+ end
1612
+ if length (fargs) >= ubidx
1613
+ if isa (argtypes[ubidx], Const)
1614
+ ub = argtypes[ubidx]. val
1615
+ elseif isType (argtypes[ubidx])
1616
+ ub = argtypes[ubidx]. parameters[1 ]
1617
+ ub_certain = false
1618
+ else
1619
+ return TypeVar
1570
1620
end
1571
- return abstract_eval_constant (UnionAll (tv, body))
1572
1621
end
1622
+ tv = TypeVar (nv, lb, ub)
1623
+ return PartialTypeVar (tv, lb_certain, ub_certain)
1624
+ end
1625
+ return TypeVar
1626
+ elseif f === UnionAll
1627
+ if length (fargs) == 3
1628
+ canconst = true
1629
+ if isa (argtypes[3 ], Const)
1630
+ body = argtypes[3 ]. val
1631
+ elseif isType (argtypes[3 ])
1632
+ body = argtypes[3 ]. parameters[1 ]
1633
+ canconst = false
1634
+ else
1635
+ return Any
1636
+ end
1637
+ if isa (argtypes[2 ], Const)
1638
+ tv = argtypes[2 ]. val
1639
+ elseif isa (argtypes[2 ], PartialTypeVar)
1640
+ ptv = argtypes[2 ]
1641
+ tv = ptv. tv
1642
+ canconst = false
1643
+ else
1644
+ return Any
1645
+ end
1646
+ ! isa (tv, TypeVar) && return Any
1647
+ (! isa (body, Type) || ! isa (body, TypeVar)) && return Any
1648
+ theunion = UnionAll (tv, body)
1649
+ ret = canconst ? abstract_eval_constant (theunion) : Type{theunion}
1650
+ return ret
1573
1651
end
1574
1652
return Any
1575
1653
elseif f === return_type
@@ -1595,7 +1673,16 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
1595
1673
1596
1674
if length (argtypes)> 2 && argtypes[3 ] ⊑ Int
1597
1675
at2 = widenconst (argtypes[2 ])
1598
- if (at2 <: Tuple ||
1676
+ if at2 <: SimpleVector && istopfunction (tm, f, :getindex )
1677
+ if isa (argtypes[2 ], Const) && isa (argtypes[3 ], Const)
1678
+ svecval = argtypes[2 ]. val
1679
+ idx = argtypes[3 ]. val
1680
+ if isa (idx, Int) && 1 <= idx <= length (svecval) &
1681
+ isassigned (svecval, idx)
1682
+ return Const (getindex (svecval, idx))
1683
+ end
1684
+ end
1685
+ elseif (at2 <: Tuple ||
1599
1686
(isa (at2, DataType) && (at2:: DataType ). name === Pair_name ()))
1600
1687
# allow tuple indexing functions to take advantage of constant
1601
1688
# index arguments.
@@ -1617,6 +1704,12 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
1617
1704
1618
1705
if istopfunction (tm, f, :promote_type ) || istopfunction (tm, f, :typejoin )
1619
1706
return Type
1707
+ elseif length (argtypes) == 2 && istopfunction (tm, f, :typename )
1708
+ t = argtypes[2 ]
1709
+ if isa (t, Const) || isType (t)
1710
+ return typename_static (t)
1711
+ end
1712
+ return Any
1620
1713
end
1621
1714
1622
1715
if sv. params. inlining
@@ -1905,6 +1998,7 @@ function widenconst(c::Const)
1905
1998
return typeof (c. val)
1906
1999
end
1907
2000
end
2001
+ widenconst (c:: PartialTypeVar ) = TypeVar
1908
2002
widenconst (t:: ANY ) = t
1909
2003
1910
2004
issubstate (a:: VarState , b:: VarState ) = (a. typ ⊑ b. typ && a. undef <= b. undef)
@@ -3552,7 +3646,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
3552
3646
if method. name == :getindex || method. name == :next || method. name == :indexed_next
3553
3647
if length (atypes) > 2 && atypes[3 ] ⊑ Int
3554
3648
at2 = widenconst (atypes[2 ])
3555
- if (at2 <: Tuple ||
3649
+ if (at2 <: Tuple || at2 <: SimpleVector ||
3556
3650
(isa (at2, DataType) && (at2:: DataType ). name === Pair_name ()))
3557
3651
force_infer = true
3558
3652
end
0 commit comments