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