@@ -63,6 +63,13 @@ immutable Const
63
63
Const (v:: ANY ) = new (v)
64
64
end
65
65
66
+ immutable PartialTypeVar
67
+ tv:: TypeVar
68
+ lb_certain:: Bool
69
+ ub_certain:: Bool
70
+ PartialTypeVar (tv:: TypeVar , lb_certain:: ANY , ub_certain:: ANY ) = new (tv, lb_certain, ub_certain)
71
+ end
72
+
66
73
function rewrap (t:: ANY , u:: ANY )
67
74
isa (t, Const) && return t
68
75
rewrap_unionall (t, u)
@@ -638,6 +645,7 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool=true, var::Union{Void,TypeVa
638
645
return (cov && ! stillcov) ? UnionAll (var, R) : R
639
646
end
640
647
648
+ const DataType_name_fieldindex = fieldindex (DataType, :name )
641
649
const DataType_parameters_fieldindex = fieldindex (DataType, :parameters )
642
650
const DataType_types_fieldindex = fieldindex (DataType, :types )
643
651
const DataType_super_fieldindex = fieldindex (DataType, :super )
@@ -671,7 +679,8 @@ function getfield_tfunc(s00::ANY, name)
671
679
if isa (sv, Module) && isa (nv, Symbol)
672
680
return abstract_eval_global (sv, nv)
673
681
end
674
- if (isa (sv, DataType) || isimmutable (sv)) && isdefined (sv, nv)
682
+ if (isa (sv, DataType) || isa (sv, SimpleVector) || isa (sv, TypeName)
683
+ || isimmutable (sv)) && isdefined (sv, nv)
675
684
return abstract_eval_constant (getfield (sv, nv))
676
685
end
677
686
end
@@ -729,7 +738,8 @@ function getfield_tfunc(s00::ANY, name)
729
738
sp = nothing
730
739
end
731
740
if (sp != = nothing &&
732
- (fld == DataType_parameters_fieldindex ||
741
+ (fld == DataType_name_fieldindex ||
742
+ fld == DataType_parameters_fieldindex ||
733
743
fld == DataType_types_fieldindex ||
734
744
fld == DataType_super_fieldindex))
735
745
return Const (getfield (sp, fld))
@@ -821,15 +831,19 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
821
831
return Any
822
832
end
823
833
uncertain = false
834
+ uncertain_typevar = false
824
835
tparams = Any[]
825
836
for i = 1 : largs
826
837
ai = args[i]
827
838
if isType (ai)
828
839
aip1 = ai. parameters[1 ]
829
840
uncertain |= has_free_typevars (aip1)
830
841
push! (tparams, aip1)
831
- elseif isa (ai, Const) && (isa (ai. val, Type) || valid_tparam (ai. val))
842
+ elseif isa (ai, Const) && (isa (ai. val, Type) || isa (ai . val, TypeVar) || valid_tparam (ai. val))
832
843
push! (tparams, ai. val)
844
+ elseif isa (ai, PartialTypeVar)
845
+ uncertain_typevar = true
846
+ push! (tparams, ai. tv)
833
847
else
834
848
# TODO : return `Bottom` for trying to apply a non-UnionAll
835
849
# if !istuple && i-1 > length(headtype.parameters)
@@ -855,7 +869,8 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
855
869
appl = headtype
856
870
uncertain = true
857
871
end
858
- ! uncertain && return Const (appl)
872
+ ! uncertain && ! uncertain_typevar && return Const (appl)
873
+ ! uncertain && return Type{appl}
859
874
if type_too_complex (appl,0 )
860
875
return Type{_} where _<: headtype
861
876
end
@@ -1386,19 +1401,62 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1386
1401
end
1387
1402
end
1388
1403
return Any
1389
- elseif f === UnionAll
1390
- if length (fargs) == 3 && isa (argtypes[2 ], Const)
1391
- tv = argtypes[2 ]. val
1392
- if isa (tv, TypeVar)
1404
+ elseif f === TypeVar
1405
+ lb = Union{}
1406
+ ub = Any
1407
+ ub_certain = lb_certain = true
1408
+ if length (fargs) >= 2 && isa (argtypes[2 ], Const)
1409
+ nv = argtypes[2 ]. val
1410
+ ubidx = 3
1411
+ if length (fargs) >= 4
1412
+ ubidx = 4
1393
1413
if isa (argtypes[3 ], Const)
1394
- body = argtypes[3 ]. val
1414
+ lb = argtypes[3 ]. val
1395
1415
elseif isType (argtypes[3 ])
1396
- body = argtypes[3 ]. parameters[1 ]
1416
+ lb = argtypes[3 ]. parameters[1 ]
1417
+ lb_certain = false
1397
1418
else
1398
- return Any
1419
+ return TypeVar
1420
+ end
1421
+ end
1422
+ if length (fargs) >= ubidx
1423
+ if isa (argtypes[ubidx], Const)
1424
+ ub = argtypes[ubidx]. val
1425
+ elseif isType (argtypes[ubidx])
1426
+ ub = argtypes[ubidx]. parameters[1 ]
1427
+ ub_certain = false
1428
+ else
1429
+ return TypeVar
1399
1430
end
1400
- return abstract_eval_constant (UnionAll (tv, body))
1401
1431
end
1432
+ tv = TypeVar (nv, lb, ub)
1433
+ return PartialTypeVar (tv, lb_certain, ub_certain)
1434
+ end
1435
+ return TypeVar
1436
+ elseif f === UnionAll
1437
+ if length (fargs) == 3
1438
+ canconst = true
1439
+ if isa (argtypes[3 ], Const)
1440
+ body = argtypes[3 ]. val
1441
+ elseif isType (argtypes[3 ])
1442
+ body = argtypes[3 ]. parameters[1 ]
1443
+ canconst = false
1444
+ else
1445
+ return Any
1446
+ end
1447
+ if isa (argtypes[2 ], Const)
1448
+ tv = argtypes[2 ]. val
1449
+ elseif isa (argtypes[2 ], PartialTypeVar)
1450
+ ptv = argtypes[2 ]
1451
+ tv = ptv. tv
1452
+ canconst = false
1453
+ else
1454
+ return Any
1455
+ end
1456
+ ! isa (tv, TypeVar) && return Any
1457
+ ret = canconst ? abstract_eval_constant (UnionAll (tv, body)) :
1458
+ Type{UnionAll (tv, body)}
1459
+ return ret
1402
1460
end
1403
1461
return Any
1404
1462
elseif f === return_type
@@ -1411,7 +1469,15 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1411
1469
tm = _topmod (sv)
1412
1470
if length (argtypes)> 2 && argtypes[3 ] ⊑ Int
1413
1471
at2 = widenconst (argtypes[2 ])
1414
- if (at2 <: Tuple ||
1472
+ if at2 <: SimpleVector && istopfunction (tm, f, :getindex )
1473
+ if isa (argtypes[2 ], Const) && isa (argtypes[3 ], Const)
1474
+ svecval = argtypes[2 ]. val
1475
+ idx = argtypes[3 ]. val
1476
+ if isa (idx, Int) && 1 <= idx <= length (svecval)
1477
+ return Const (getindex (svecval, idx))
1478
+ end
1479
+ end
1480
+ elseif (at2 <: Tuple ||
1415
1481
(isa (at2, DataType) && (at2:: DataType ). name === Pair_name ()))
1416
1482
# allow tuple indexing functions to take advantage of constant
1417
1483
# index arguments.
@@ -1433,6 +1499,17 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1433
1499
1434
1500
if istopfunction (tm, f, :promote_type ) || istopfunction (tm, f, :typejoin )
1435
1501
return Type
1502
+ elseif length (argtypes) == 2 && istopfunction (tm, f, :typename )
1503
+ t = argtypes[2 ]
1504
+ if isa (t, Const) || isType (t)
1505
+ val = isa (t, Const) ? t. val : t. parameters[1 ]
1506
+ try
1507
+ return Const (typename (val))
1508
+ catch
1509
+ return Union{}
1510
+ end
1511
+ end
1512
+ return Any
1436
1513
end
1437
1514
1438
1515
if sv. params. inlining
@@ -1683,6 +1760,7 @@ function ⊑(a::ANY, b::ANY)
1683
1760
end
1684
1761
1685
1762
widenconst (c:: Const ) = isa (c. val, Type) ? Type{c. val} : typeof (c. val)
1763
+ widenconst (c:: PartialTypeVar ) = TypeVar
1686
1764
widenconst (t:: ANY ) = t
1687
1765
1688
1766
issubstate (a:: VarState , b:: VarState ) = (a. typ ⊑ b. typ && a. undef <= b. undef)
0 commit comments