@@ -46,7 +46,7 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int)
4646 # see if it is derived from the body
4747 # also handle the var here, since this construct bounds the mindepth to the smallest possible value
4848 return is_derived_type (t, c. var. ub, mindepth) || is_derived_type (t, c. body, mindepth)
49- elseif isa (c, Core . TypeofVararg )
49+ elseif isvarargtype (c )
5050 return is_derived_type (t, unwrapva (c), mindepth)
5151 elseif isa (c, DataType)
5252 if mindepth > 0
7979# The goal of this function is to return a type of greater "size" and less "complexity" than
8080# both `t` or `c` over the lattice defined by `sources`, `depth`, and `allowed_tuplelen`.
8181function _limit_type_size (@nospecialize (t), @nospecialize (c), sources:: SimpleVector , depth:: Int , allowed_tuplelen:: Int )
82+ @assert isa (t, Type) && isa (c, Type) " unhandled TypeVar / Vararg"
8283 if t === c
8384 return t # quick egal test
8485 elseif t === Union{}
@@ -98,40 +99,22 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
9899 # first attempt to turn `c` into a type that contributes meaningful information
99100 # by peeling off meaningless non-matching wrappers of comparison one at a time
100101 # then unwrap `t`
101- if isa (c, TypeVar)
102- if isa (t, TypeVar) && t. ub === c. ub && (t. lb === Union{} || t. lb === c. lb)
103- return t # it's ok to change the name, or widen `lb` to Union{}, so we can handle this immediately here
104- end
105- return _limit_type_size (t, c. ub, sources, depth, allowed_tuplelen)
106- end
102+ # NOTE that `TypeVar` / `Vararg` are handled separately to catch the logic errors
107103 if isa (c, UnionAll)
108- return _limit_type_size (t, c. body, sources, depth, allowed_tuplelen)
104+ return __limit_type_size (t, c. body, sources, depth, allowed_tuplelen):: Type
109105 end
110106 if isa (t, UnionAll)
111- tbody = _limit_type_size (t. body, c, sources, depth, allowed_tuplelen)
107+ tbody = __limit_type_size (t. body, c, sources, depth, allowed_tuplelen)
112108 tbody === t. body && return t
113- return UnionAll (t. var, tbody)
114- elseif isa (t, TypeVar)
115- # don't have a matching TypeVar in comparison, so we keep just the upper bound
116- return _limit_type_size (t. ub, c, sources, depth, allowed_tuplelen)
109+ return UnionAll (t. var, tbody):: Type
117110 elseif isa (t, Union)
118111 if isa (c, Union)
119- a = _limit_type_size (t. a, c. a, sources, depth, allowed_tuplelen)
120- b = _limit_type_size (t. b, c. b, sources, depth, allowed_tuplelen)
112+ a = __limit_type_size (t. a, c. a, sources, depth, allowed_tuplelen)
113+ b = __limit_type_size (t. b, c. b, sources, depth, allowed_tuplelen)
121114 return Union{a, b}
122115 end
123- elseif isa (t, Core. TypeofVararg)
124- isa (c, Core. TypeofVararg) || return Vararg
125- VaT = _limit_type_size (unwrapva (t), unwrapva (c), sources, depth + 1 , 0 )
126- if isdefined (t, :N ) && (isa (t. N, TypeVar) || (isdefined (c, :N ) && t. N === c. N))
127- return Vararg{VaT, t. N}
128- end
129- return Vararg{VaT}
130116 elseif isa (t, DataType)
131- if isa (c, Core. TypeofVararg)
132- # Tuple{Vararg{T}} --> Tuple{T} is OK
133- return _limit_type_size (t, unwrapva (c), sources, depth, 0 )
134- elseif isType (t) # allow taking typeof as Type{...}, but ensure it doesn't start nesting
117+ if isType (t) # allow taking typeof as Type{...}, but ensure it doesn't start nesting
135118 tt = unwrap_unionall (t. parameters[1 ])
136119 (! isa (tt, DataType) || isType (tt)) && (depth += 1 )
137120 is_derived_type_from_any (tt, sources, depth) && return t
@@ -161,7 +144,7 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
161144 else
162145 cPi = Any
163146 end
164- Q[i] = _limit_type_size (Q[i], cPi, sources, depth + 1 , 0 )
147+ Q[i] = __limit_type_size (Q[i], cPi, sources, depth + 1 , 0 )
165148 end
166149 return Tuple{Q... }
167150 end
@@ -182,6 +165,31 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
182165 return Any
183166end
184167
168+ # helper function of `_limit_type_size`, which has the right to take and return `TypeVar` / `Vararg`
169+ function __limit_type_size (@nospecialize (t), @nospecialize (c), sources:: SimpleVector , depth:: Int , allowed_tuplelen:: Int )
170+ if isa (c, TypeVar)
171+ if isa (t, TypeVar) && t. ub === c. ub && (t. lb === Union{} || t. lb === c. lb)
172+ return t # it's ok to change the name, or widen `lb` to Union{}, so we can handle this immediately here
173+ end
174+ return __limit_type_size (t, c. ub, sources, depth, allowed_tuplelen)
175+ elseif isa (t, TypeVar)
176+ # don't have a matching TypeVar in comparison, so we keep just the upper bound
177+ return __limit_type_size (t. ub, c, sources, depth, allowed_tuplelen)
178+ elseif isvarargtype (t)
179+ isvarargtype (c) || return Vararg
180+ VaT = __limit_type_size (unwrapva (t), unwrapva (c), sources, depth + 1 , 0 )
181+ if isdefined (t, :N ) && (isa (t. N, TypeVar) || (isdefined (c, :N ) && t. N === c. N))
182+ return Vararg{VaT, t. N}
183+ end
184+ return Vararg{VaT}
185+ elseif isvarargtype (c)
186+ # Tuple{Vararg{T}} --> Tuple{T} is OK
187+ return __limit_type_size (t, unwrapva (c), sources, depth, 0 )
188+ else
189+ return _limit_type_size (t, c, sources, depth, allowed_tuplelen)
190+ end
191+ end
192+
185193function type_more_complex (@nospecialize (t), @nospecialize (c), sources:: SimpleVector , depth:: Int , tupledepth:: Int , allowed_tuplelen:: Int )
186194 # detect cases where the comparison is trivial
187195 if t === c
@@ -225,13 +233,13 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
225233 return t != = 1 && ! (0 <= t < c) # alternatively, could use !(abs(t) <= abs(c) || abs(t) < n) for some n
226234 end
227235 # base case for data types
228- if isa (t, Core . TypeofVararg )
229- if isa (c, Core . TypeofVararg )
236+ if isvarargtype (t )
237+ if isvarargtype (c )
230238 return type_more_complex (unwrapva (t), unwrapva (c), sources, depth + 1 , tupledepth, 0 )
231239 end
232240 elseif isa (t, DataType)
233241 tP = t. parameters
234- if isa (c, Core . TypeofVararg )
242+ if isvarargtype (c )
235243 return type_more_complex (t, unwrapva (c), sources, depth, tupledepth, 0 )
236244 elseif isType (t) # allow taking typeof any source type anywhere as Type{...}, as long as it isn't nesting Type{Type{...}}
237245 tt = unwrap_unionall (t. parameters[1 ])
@@ -604,10 +612,11 @@ function tmeet(@nospecialize(v), @nospecialize(t))
604612 @assert widev <: Tuple
605613 new_fields = Vector {Any} (undef, length (v. fields))
606614 for i = 1 : length (new_fields)
607- if isa (v. fields[i], Core. TypeofVararg)
608- new_fields[i] = v. fields[i]
615+ vfi = v. fields[i]
616+ if isvarargtype (vfi)
617+ new_fields[i] = vfi
609618 else
610- new_fields[i] = tmeet (v . fields[i] , widenconst (getfield_tfunc (t, Const (i))))
619+ new_fields[i] = tmeet (vfi , widenconst (getfield_tfunc (t, Const (i))))
611620 if new_fields[i] === Bottom
612621 return Bottom
613622 end
0 commit comments