@@ -46,7 +46,7 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int)
46
46
# see if it is derived from the body
47
47
# also handle the var here, since this construct bounds the mindepth to the smallest possible value
48
48
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 )
50
50
return is_derived_type (t, unwrapva (c), mindepth)
51
51
elseif isa (c, DataType)
52
52
if mindepth > 0
79
79
# The goal of this function is to return a type of greater "size" and less "complexity" than
80
80
# both `t` or `c` over the lattice defined by `sources`, `depth`, and `allowed_tuplelen`.
81
81
function _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"
82
83
if t === c
83
84
return t # quick egal test
84
85
elseif t === Union{}
@@ -98,40 +99,22 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
98
99
# first attempt to turn `c` into a type that contributes meaningful information
99
100
# by peeling off meaningless non-matching wrappers of comparison one at a time
100
101
# 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
107
103
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
109
105
end
110
106
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)
112
108
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
117
110
elseif isa (t, Union)
118
111
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)
121
114
return Union{a, b}
122
115
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}
130
116
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
135
118
tt = unwrap_unionall (t. parameters[1 ])
136
119
(! isa (tt, DataType) || isType (tt)) && (depth += 1 )
137
120
is_derived_type_from_any (tt, sources, depth) && return t
@@ -161,7 +144,7 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
161
144
else
162
145
cPi = Any
163
146
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 )
165
148
end
166
149
return Tuple{Q... }
167
150
end
@@ -182,6 +165,31 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
182
165
return Any
183
166
end
184
167
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
+
185
193
function type_more_complex (@nospecialize (t), @nospecialize (c), sources:: SimpleVector , depth:: Int , tupledepth:: Int , allowed_tuplelen:: Int )
186
194
# detect cases where the comparison is trivial
187
195
if t === c
@@ -225,13 +233,13 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
225
233
return t != = 1 && ! (0 <= t < c) # alternatively, could use !(abs(t) <= abs(c) || abs(t) < n) for some n
226
234
end
227
235
# 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 )
230
238
return type_more_complex (unwrapva (t), unwrapva (c), sources, depth + 1 , tupledepth, 0 )
231
239
end
232
240
elseif isa (t, DataType)
233
241
tP = t. parameters
234
- if isa (c, Core . TypeofVararg )
242
+ if isvarargtype (c )
235
243
return type_more_complex (t, unwrapva (c), sources, depth, tupledepth, 0 )
236
244
elseif isType (t) # allow taking typeof any source type anywhere as Type{...}, as long as it isn't nesting Type{Type{...}}
237
245
tt = unwrap_unionall (t. parameters[1 ])
@@ -603,10 +611,11 @@ function tmeet(@nospecialize(v), @nospecialize(t))
603
611
@assert widev <: Tuple
604
612
new_fields = Vector {Any} (undef, length (v. fields))
605
613
for i = 1 : length (new_fields)
606
- if isa (v. fields[i], Core. TypeofVararg)
607
- new_fields[i] = v. fields[i]
614
+ vfi = v. fields[i]
615
+ if isvarargtype (vfi)
616
+ new_fields[i] = vfi
608
617
else
609
- new_fields[i] = tmeet (v . fields[i] , widenconst (getfield_tfunc (t, Const (i))))
618
+ new_fields[i] = tmeet (vfi , widenconst (getfield_tfunc (t, Const (i))))
610
619
if new_fields[i] === Bottom
611
620
return Bottom
612
621
end
0 commit comments