@@ -39,15 +39,15 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int)
3939 if t === c
4040 return mindepth <= 1
4141 end
42+ isvarargtype (t) && (t = unwrapva (t))
43+ isvarargtype (c) && (c = unwrapva (c))
4244 if isa (c, Union)
4345 # see if it is one of the elements of the union
4446 return is_derived_type (t, c. a, mindepth) || is_derived_type (t, c. b, mindepth)
4547 elseif isa (c, UnionAll)
4648 # see if it is derived from the body
4749 # also handle the var here, since this construct bounds the mindepth to the smallest possible value
4850 return is_derived_type (t, c. var. ub, mindepth) || is_derived_type (t, c. body, mindepth)
49- elseif isvarargtype (c)
50- return is_derived_type (t, unwrapva (c), mindepth)
5151 elseif isa (c, DataType)
5252 if mindepth > 0
5353 mindepth -= 1
@@ -114,10 +114,14 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
114114 return Union{a, b}
115115 end
116116 elseif isa (t, DataType)
117- if isType (t) # allow taking typeof as Type{...}, but ensure it doesn't start nesting
117+ if isType (t) # see equivalent case in type_more_complex
118118 tt = unwrap_unionall (t. parameters[1 ])
119- (! isa (tt, DataType) || isType (tt)) && (depth += 1 )
120- is_derived_type_from_any (tt, sources, depth) && return t
119+ if isa (tt, Union) || isa (tt, TypeVar) || isType (tt)
120+ is_derived_type_from_any (tt, sources, depth + 1 ) && return t
121+ else
122+ isType (c) && (c = unwrap_unionall (c. parameters[1 ]))
123+ type_more_complex (tt, c, sources, depth, 0 , 0 ) || return t
124+ end
121125 return Type
122126 elseif isa (c, DataType)
123127 tP = t. parameters
167171
168172# helper function of `_limit_type_size`, which has the right to take and return `TypeVar` / `Vararg`
169173function __limit_type_size (@nospecialize (t), @nospecialize (c), sources:: SimpleVector , depth:: Int , allowed_tuplelen:: Int )
174+ cN = 0
175+ if isvarargtype (c) # Tuple{Vararg{T}} --> Tuple{T} is OK
176+ isdefined (c, :N ) && (cN = c. N)
177+ c = unwrapva (c)
178+ end
170179 if isa (c, TypeVar)
171180 if isa (t, TypeVar) && t. ub === c. ub && (t. lb === Union{} || t. lb === c. lb)
172181 return t # it's ok to change the name, or widen `lb` to Union{}, so we can handle this immediately here
@@ -176,15 +185,17 @@ function __limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVe
176185 # don't have a matching TypeVar in comparison, so we keep just the upper bound
177186 return __limit_type_size (t. ub, c, sources, depth, allowed_tuplelen)
178187 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}
188+ # Tuple{Vararg{T,N}} --> Tuple{Vararg{S,M}} is OK
189+ # Tuple{T} --> Tuple{Vararg{T}} is OK
190+ # but S must be more limited than T, and must not introduce a new number for M
191+ VaT = __limit_type_size (unwrapva (t), c, sources, depth + 1 , 0 )
192+ if isdefined (t, :N )
193+ tN = t. N
194+ if isa (tN, TypeVar) || tN === cN
195+ return Vararg{VaT, tN}
196+ end
183197 end
184198 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 )
188199 else
189200 return _limit_type_size (t, c, sources, depth, allowed_tuplelen)
190201 end
@@ -205,6 +216,8 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
205216 return false # t isn't something new
206217 end
207218 # peel off wrappers
219+ isvarargtype (t) && (t = unwrapva (t))
220+ isvarargtype (c) && (c = unwrapva (c))
208221 if isa (c, UnionAll)
209222 # allow wrapping type with fewer UnionAlls than comparison if in a covariant context
210223 if ! isa (t, UnionAll) && tupledepth == 0
@@ -233,18 +246,19 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
233246 return t != = 1 && ! (0 <= t < c) # alternatively, could use !(abs(t) <= abs(c) || abs(t) < n) for some n
234247 end
235248 # base case for data types
236- if isvarargtype (t)
237- if isvarargtype (c)
238- return type_more_complex (unwrapva (t), unwrapva (c), sources, depth + 1 , tupledepth, 0 )
239- end
240- elseif isa (t, DataType)
249+ if isa (t, DataType)
241250 tP = t. parameters
242- if isvarargtype (c)
243- return type_more_complex (t, unwrapva (c), sources, depth, tupledepth, 0 )
244- elseif isType (t) # allow taking typeof any source type anywhere as Type{...}, as long as it isn't nesting Type{Type{...}}
251+ if isType (t)
252+ # Treat Type{T} and T as equivalent to allow taking typeof any
253+ # source type (DataType) anywhere as Type{...}, as long as it isn't
254+ # nesting as Type{Type{...}}
245255 tt = unwrap_unionall (t. parameters[1 ])
246- (! isa (tt, DataType) || isType (tt)) && (depth += 1 )
247- return ! is_derived_type_from_any (tt, sources, depth)
256+ if isa (tt, Union) || isa (tt, TypeVar) || isType (tt)
257+ return ! is_derived_type_from_any (tt, sources, depth + 1 )
258+ else
259+ isType (c) && (c = unwrap_unionall (c. parameters[1 ]))
260+ return type_more_complex (tt, c, sources, depth, 0 , 0 )
261+ end
248262 elseif isa (c, DataType) && t. name === c. name
249263 cP = c. parameters
250264 length (cP) < length (tP) && return true
0 commit comments