Skip to content

Commit eb504bb

Browse files
martinholtersJeffBezanson
authored andcommitted
Allow limit_type_depth to introduce more than one new TypeVar (#20626)
Allow `limit_type_depth` to introduce more than one new `TypeVar` Assert `limit_type_depth` returns a supertype of its input Fixes #20615.
1 parent fec29e7 commit eb504bb

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

base/inference.jl

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -660,21 +660,27 @@ function type_depth(t::ANY)
660660
return 0
661661
end
662662

663-
function limit_type_depth(t::ANY, d::Int, cov::Bool=true, var::Union{Void,TypeVar}=nothing)
663+
function limit_type_depth(t::ANY, d::Int)
664+
r = limit_type_depth(t, d, true, TypeVar[])
665+
@assert !isa(t, Type) || t <: r
666+
return r
667+
end
668+
669+
function limit_type_depth(t::ANY, d::Int, cov::Bool, vars::Vector{TypeVar}=TypeVar[])
664670
if isa(t,Union)
665671
if d > MAX_TYPE_DEPTH
666672
return Any
667673
end
668-
return Union{map(x->limit_type_depth(x, d+1, cov, var), (t.a,t.b))...}
674+
return Union{map(x->limit_type_depth(x, d+1, cov, vars), (t.a,t.b))...}
669675
elseif isa(t,UnionAll)
670676
v = t.var
671677
if v.ub === Any
672678
if v.lb === Bottom
673-
return UnionAll(t.var, limit_type_depth(t.body, d, cov, var))
679+
return UnionAll(t.var, limit_type_depth(t.body, d, cov, vars))
674680
end
675681
ub = Any
676682
else
677-
ub = limit_type_depth(v.ub, d+1, true, nothing)
683+
ub = limit_type_depth(v.ub, d+1, true)
678684
end
679685
if v.lb === Bottom || type_depth(v.lb) > MAX_TYPE_DEPTH
680686
# note: lower bounds need to be widened by making them lower
@@ -683,25 +689,27 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool=true, var::Union{Void,TypeVa
683689
lb = v.lb
684690
end
685691
v2 = TypeVar(v.name, lb, ub)
686-
return UnionAll(v2, limit_type_depth(t{v2}, d, cov, var))
692+
return UnionAll(v2, limit_type_depth(t{v2}, d, cov, vars))
687693
elseif !isa(t,DataType)
688694
return t
689695
end
690696
P = t.parameters
691697
isempty(P) && return t
692698
if d > MAX_TYPE_DEPTH
693699
cov && return t.name.wrapper
694-
# TODO mutating a TypeVar is not great style
695-
var.ub = t.name.wrapper
700+
var = TypeVar(:_, t.name.wrapper)
701+
push!(vars, var)
696702
return var
697703
end
698704
stillcov = cov && (t.name === Tuple.name)
705+
Q = map(x->limit_type_depth(x, d+1, stillcov, vars), P)
706+
R = t.name.wrapper{Q...}
699707
if cov && !stillcov
700-
var = TypeVar(:_)
708+
for var in vars
709+
R = UnionAll(var, R)
710+
end
701711
end
702-
Q = map(x->limit_type_depth(x, d+1, stillcov, var), P)
703-
R = t.name.wrapper{Q...}
704-
return (cov && !stillcov) ? UnionAll(var, R) : R
712+
return R
705713
end
706714

707715
const DataType_name_fieldindex = fieldindex(DataType, :name)

test/inference.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,3 +642,9 @@ end
642642
# infinite type growth via lower bounds (formed by intersection)
643643
f20267(x::T20267{T}, y::T) where (T) = f20267(Any[1][1], x.inds)
644644
@test Base.return_types(f20267, (Any, Any)) == Any[Union{}]
645+
646+
# issue #20615
647+
let A = 1:2, z = zip(A, A, A, A, A, A, A, A, A, A, A, A)
648+
@test z isa Core.Inference.limit_type_depth(typeof(z), 0)
649+
@test start(z) == (1, (1, (1, (1, (1, (1, (1, (1, (1, (1, (1, 1)))))))))))
650+
end

0 commit comments

Comments
 (0)