@@ -39,15 +39,15 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int)
39
39
if t === c
40
40
return mindepth <= 1
41
41
end
42
+ isvarargtype (t) && (t = unwrapva (t))
43
+ isvarargtype (c) && (c = unwrapva (c))
42
44
if isa (c, Union)
43
45
# see if it is one of the elements of the union
44
46
return is_derived_type (t, c. a, mindepth) || is_derived_type (t, c. b, mindepth)
45
47
elseif isa (c, UnionAll)
46
48
# see if it is derived from the body
47
49
# also handle the var here, since this construct bounds the mindepth to the smallest possible value
48
50
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)
51
51
elseif isa (c, DataType)
52
52
if mindepth > 0
53
53
mindepth -= 1
@@ -114,10 +114,14 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
114
114
return Union{a, b}
115
115
end
116
116
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
118
118
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
121
125
return Type
122
126
elseif isa (c, DataType)
123
127
tP = t. parameters
167
171
168
172
# helper function of `_limit_type_size`, which has the right to take and return `TypeVar` / `Vararg`
169
173
function __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
170
179
if isa (c, TypeVar)
171
180
if isa (t, TypeVar) && t. ub === c. ub && (t. lb === Union{} || t. lb === c. lb)
172
181
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
176
185
# don't have a matching TypeVar in comparison, so we keep just the upper bound
177
186
return __limit_type_size (t. ub, c, sources, depth, allowed_tuplelen)
178
187
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
183
197
end
184
198
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
199
else
189
200
return _limit_type_size (t, c, sources, depth, allowed_tuplelen)
190
201
end
@@ -205,6 +216,8 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
205
216
return false # t isn't something new
206
217
end
207
218
# peel off wrappers
219
+ isvarargtype (t) && (t = unwrapva (t))
220
+ isvarargtype (c) && (c = unwrapva (c))
208
221
if isa (c, UnionAll)
209
222
# allow wrapping type with fewer UnionAlls than comparison if in a covariant context
210
223
if ! isa (t, UnionAll) && tupledepth == 0
@@ -233,18 +246,19 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
233
246
return t != = 1 && ! (0 <= t < c) # alternatively, could use !(abs(t) <= abs(c) || abs(t) < n) for some n
234
247
end
235
248
# 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)
241
250
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{...}}
245
255
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
248
262
elseif isa (c, DataType) && t. name === c. name
249
263
cP = c. parameters
250
264
length (cP) < length (tP) && return true
0 commit comments