@@ -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
@@ -1352,6 +1367,25 @@ function Pair_name()
1352
1367
return _Pair_name
1353
1368
end
1354
1369
1370
+ _typename (a) = Union{}
1371
+ _typename (a:: Vararg ) = Any
1372
+ _typename (a:: TypeVar ) = Any
1373
+ _typename (a:: DataType ) = Const (a. name)
1374
+ function _typename (a:: Union )
1375
+ ta = _typename (a. a)
1376
+ tb = _typename (a. b)
1377
+ ta == tb ? tb : (ta === Any || tb == Any) ? Any : Union{}
1378
+ end
1379
+ _typename (union:: UnionAll ) = typename (union. body)
1380
+ function typename_static (t)
1381
+ # N.B.: typename maps type equivalence classes to a single value
1382
+ if isa (t, Const) || isType (t)
1383
+ return _typename (isa (t, Const) ? t. val : t. parameters[1 ])
1384
+ else
1385
+ return Any
1386
+ end
1387
+ end
1388
+
1355
1389
function abstract_call (f:: ANY , fargs, argtypes:: Vector{Any} , vtypes:: VarTable , sv:: InferenceState )
1356
1390
if f === _apply
1357
1391
length (fargs) > 1 || return Any
@@ -1386,19 +1420,62 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1386
1420
end
1387
1421
end
1388
1422
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)
1423
+ elseif f === TypeVar
1424
+ lb = Union{}
1425
+ ub = Any
1426
+ ub_certain = lb_certain = true
1427
+ if length (fargs) >= 2 && isa (argtypes[2 ], Const)
1428
+ nv = argtypes[2 ]. val
1429
+ ubidx = 3
1430
+ if length (fargs) >= 4
1431
+ ubidx = 4
1393
1432
if isa (argtypes[3 ], Const)
1394
- body = argtypes[3 ]. val
1433
+ lb = argtypes[3 ]. val
1395
1434
elseif isType (argtypes[3 ])
1396
- body = argtypes[3 ]. parameters[1 ]
1435
+ lb = argtypes[3 ]. parameters[1 ]
1436
+ lb_certain = false
1397
1437
else
1398
- return Any
1438
+ return TypeVar
1399
1439
end
1400
- return abstract_eval_constant (UnionAll (tv, body))
1401
1440
end
1441
+ if length (fargs) >= ubidx
1442
+ if isa (argtypes[ubidx], Const)
1443
+ ub = argtypes[ubidx]. val
1444
+ elseif isType (argtypes[ubidx])
1445
+ ub = argtypes[ubidx]. parameters[1 ]
1446
+ ub_certain = false
1447
+ else
1448
+ return TypeVar
1449
+ end
1450
+ end
1451
+ tv = TypeVar (nv, lb, ub)
1452
+ return PartialTypeVar (tv, lb_certain, ub_certain)
1453
+ end
1454
+ return TypeVar
1455
+ elseif f === UnionAll
1456
+ if length (fargs) == 3
1457
+ canconst = true
1458
+ if isa (argtypes[3 ], Const)
1459
+ body = argtypes[3 ]. val
1460
+ elseif isType (argtypes[3 ])
1461
+ body = argtypes[3 ]. parameters[1 ]
1462
+ canconst = false
1463
+ else
1464
+ return Any
1465
+ end
1466
+ if isa (argtypes[2 ], Const)
1467
+ tv = argtypes[2 ]. val
1468
+ elseif isa (argtypes[2 ], PartialTypeVar)
1469
+ ptv = argtypes[2 ]
1470
+ tv = ptv. tv
1471
+ canconst = false
1472
+ else
1473
+ return Any
1474
+ end
1475
+ ! isa (tv, TypeVar) && return Any
1476
+ ret = canconst ? abstract_eval_constant (UnionAll (tv, body)) :
1477
+ Type{UnionAll (tv, body)}
1478
+ return ret
1402
1479
end
1403
1480
return Any
1404
1481
elseif f === return_type
@@ -1411,7 +1488,15 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1411
1488
tm = _topmod (sv)
1412
1489
if length (argtypes)> 2 && argtypes[3 ] ⊑ Int
1413
1490
at2 = widenconst (argtypes[2 ])
1414
- if (at2 <: Tuple ||
1491
+ if at2 <: SimpleVector && istopfunction (tm, f, :getindex )
1492
+ if isa (argtypes[2 ], Const) && isa (argtypes[3 ], Const)
1493
+ svecval = argtypes[2 ]. val
1494
+ idx = argtypes[3 ]. val
1495
+ if isa (idx, Int) && 1 <= idx <= length (svecval)
1496
+ return Const (getindex (svecval, idx))
1497
+ end
1498
+ end
1499
+ elseif (at2 <: Tuple ||
1415
1500
(isa (at2, DataType) && (at2:: DataType ). name === Pair_name ()))
1416
1501
# allow tuple indexing functions to take advantage of constant
1417
1502
# index arguments.
@@ -1433,6 +1518,12 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1433
1518
1434
1519
if istopfunction (tm, f, :promote_type ) || istopfunction (tm, f, :typejoin )
1435
1520
return Type
1521
+ elseif length (argtypes) == 2 && istopfunction (tm, f, :typename )
1522
+ t = argtypes[2 ]
1523
+ if isa (t, Const) || isType (t)
1524
+ return typename_static (t)
1525
+ end
1526
+ return Any
1436
1527
end
1437
1528
1438
1529
if sv. params. inlining
@@ -1683,6 +1774,7 @@ function ⊑(a::ANY, b::ANY)
1683
1774
end
1684
1775
1685
1776
widenconst (c:: Const ) = isa (c. val, Type) ? Type{c. val} : typeof (c. val)
1777
+ widenconst (c:: PartialTypeVar ) = TypeVar
1686
1778
widenconst (t:: ANY ) = t
1687
1779
1688
1780
issubstate (a:: VarState , b:: VarState ) = (a. typ ⊑ b. typ && a. undef <= b. undef)
@@ -3300,7 +3392,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
3300
3392
if method. name == :getindex || method. name == :next || method. name == :indexed_next
3301
3393
if length (atypes) > 2 && atypes[3 ] ⊑ Int
3302
3394
at2 = widenconst (atypes[2 ])
3303
- if (at2 <: Tuple ||
3395
+ if (at2 <: Tuple || at2 <: SimpleVector ||
3304
3396
(isa (at2, DataType) && (at2:: DataType ). name === Pair_name ()))
3305
3397
force_infer = true
3306
3398
end
0 commit comments