Skip to content

Commit eeacba5

Browse files
committed
add typemap filtering option for Union{}
Based on the new morespecific rule for Union{} and method definitions of the specific form `f(..., Type{Union{}}, Vararg)`. If a method definition exists with that specific form, the intersection visitor will ignore all intersections that have that as their only result, saving significant effort when working with lookups involving `Type{<:T}` (which usually ended up mostly ambiguous anyways). Fixes: #33780 This pattern turns out to have still to been making package loading slow. We could keep adding methods following the ambiguity pattern #46000 for the couple specific functions that need it (constructor, eltype, IteratorEltype, IteratorSize, and maybe a couple others) so the internals can detect those and optimize functions that have that method pair. But it seems somewhat odd, convoluted, and non-obvious behavior there. Instead, this breaks all ambiguities in which Union{} is present explicitly in favor of the method with Union{}. This means that when computing method matches, as soon as we see one method definition with Union{}, we can record that the method is the only possible match for that slot. This, in essence, permits creating a rule for dispatch that a TypeVar lower bound must be strictly a supertype of Union{}, but this creates it at the function level, instead of expecting the user to add it to every TypeVar they use to define methods. This also lets us improve the error message for these cases (generally they should error to avoid polluting the inference result), since we can be assured this method will be called, and not result in an ambiguous MethodError instead! Reverts the functional change of #46000
1 parent 28448db commit eeacba5

28 files changed

+215
-107
lines changed

base/abstractarray.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,13 @@ CartesianIndex{2}
183183
For arrays, this function requires at least Julia 1.2.
184184
"""
185185
keytype(a::AbstractArray) = keytype(typeof(a))
186+
keytype(::Type{Union{}}, slurp...) = eltype(Union{})
186187

187188
keytype(A::Type{<:AbstractArray}) = CartesianIndex{ndims(A)}
188189
keytype(A::Type{<:AbstractVector}) = Int
189190

190191
valtype(a::AbstractArray) = valtype(typeof(a))
192+
valtype(::Type{Union{}}, slurp...) = eltype(Union{})
191193

192194
"""
193195
valtype(T::Type{<:AbstractArray})
@@ -232,7 +234,7 @@ UInt8
232234
```
233235
"""
234236
eltype(::Type) = Any
235-
eltype(::Type{Bottom}) = throw(ArgumentError("Union{} does not have elements"))
237+
eltype(::Type{Bottom}, slurp...) = throw(ArgumentError("Union{} does not have elements"))
236238
eltype(x) = eltype(typeof(x))
237239
eltype(::Type{<:AbstractArray{E}}) where {E} = @isdefined(E) ? E : Any
238240

@@ -268,6 +270,7 @@ julia> ndims(A)
268270
"""
269271
ndims(::AbstractArray{T,N}) where {T,N} = N
270272
ndims(::Type{<:AbstractArray{<:Any,N}}) where {N} = N
273+
ndims(::Type{Union{}}, slurp...) = throw(ArgumentError("Union{} does not have elements"))
271274

272275
"""
273276
length(collection) -> Integer

base/array.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,10 @@ function bitsunionsize(u::Union)
252252
return sz
253253
end
254254

255+
# Deprecate this, as it seems to have no documented meaning and is unused here,
256+
# but is frequently accessed in packages
255257
elsize(@nospecialize _::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
258+
elsize(::Type{Union{}}, slurp...) = 0
256259
sizeof(a::Array) = Core.sizeof(a)
257260

258261
function isassigned(a::Array, i::Int...)

base/arrayshow.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,10 @@ end
540540
# returning Any, as this would cause incorrect printing in e.g. `Vector[Any[1]]`,
541541
# because eltype(Vector) == Any so `Any` wouldn't be printed in `Any[1]`)
542542
typeinfo_eltype(typeinfo) = nothing # element type not precisely known
543-
typeinfo_eltype(typeinfo::Type{<:AbstractArray{T}}) where {T} = eltype(typeinfo)
544-
typeinfo_eltype(typeinfo::Type{<:AbstractDict{K,V}}) where {K,V} = eltype(typeinfo)
545-
typeinfo_eltype(typeinfo::Type{<:AbstractSet{T}}) where {T} = eltype(typeinfo)
543+
typeinfo_eltype(typeinfo::Type{Union{}}, slurp...) = nothing
544+
typeinfo_eltype(typeinfo::Type{<:AbstractArray}) = eltype(typeinfo)
545+
typeinfo_eltype(typeinfo::Type{<:AbstractDict}) = eltype(typeinfo)
546+
typeinfo_eltype(typeinfo::Type{<:AbstractSet}) = eltype(typeinfo)
546547

547548
# types that can be parsed back accurately from their un-decorated representations
548549
function typeinfo_implicit(@nospecialize(T))

base/boot.jl

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,17 @@ UnionAll(v::TypeVar, @nospecialize(t)) = ccall(:jl_type_unionall, Any, (Any, Any
258258

259259
const Vararg = ccall(:jl_toplevel_eval_in, Any, (Any, Any), Core, _expr(:new, TypeofVararg))
260260

261-
# let the compiler assume that calling Union{} as a constructor does not need
262-
# to be considered ever (which comes up often as Type{<:T})
263-
Union{}(a...) = throw(MethodError(Union{}, a))
261+
# dispatch token indicating a kwarg (keyword sorter) call
262+
function kwcall end
263+
# deprecated internal functions:
264+
kwfunc(@nospecialize(f)) = kwcall
265+
kwftype(@nospecialize(t)) = typeof(kwcall)
266+
267+
# Let the compiler assume that calling Union{} as a constructor does not need
268+
# to be considered ever (which comes up often as Type{<:T} inference, and
269+
# occasionally in user code from eltype).
270+
Union{}(a...) = throw(ArgumentError("cannot construct a value of type Union{} for return result"))
271+
kwcall(kwargs, ::Type{Union{}}, a...) = Union{}(a...)
264272

265273
Expr(@nospecialize args...) = _expr(args...)
266274

@@ -369,12 +377,6 @@ include(m::Module, fname::String) = ccall(:jl_load_, Any, (Any, Any), m, fname)
369377

370378
eval(m::Module, @nospecialize(e)) = ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e)
371379

372-
# dispatch token indicating a kwarg (keyword sorter) call
373-
function kwcall end
374-
# deprecated internal functions:
375-
kwfunc(@nospecialize(f)) = kwcall
376-
kwftype(@nospecialize(t)) = typeof(kwcall)
377-
378380
mutable struct Box
379381
contents::Any
380382
Box(@nospecialize(x)) = new(x)

base/broadcast.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ that you may be able to leverage; see the
3434
"""
3535
abstract type BroadcastStyle end
3636

37+
struct Unknown <: BroadcastStyle end
38+
BroadcastStyle(::Type{Union{}}, slurp...) = Unknown() # ambiguity resolution
39+
3740
"""
3841
`Broadcast.Style{C}()` defines a [`BroadcastStyle`](@ref) signaling through the type
3942
parameter `C`. You can use this as an alternative to creating custom subtypes of `BroadcastStyle`,
@@ -45,9 +48,6 @@ struct Style{T} <: BroadcastStyle end
4548

4649
BroadcastStyle(::Type{<:Tuple}) = Style{Tuple}()
4750

48-
struct Unknown <: BroadcastStyle end
49-
BroadcastStyle(::Type{Union{}}) = Unknown() # ambiguity resolution
50-
5151
"""
5252
`Broadcast.AbstractArrayStyle{N} <: BroadcastStyle` is the abstract supertype for any style
5353
associated with an `AbstractArray` type.

base/complex.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ Float64
120120
real(T::Type) = typeof(real(zero(T)))
121121
real(::Type{T}) where {T<:Real} = T
122122
real(C::Type{<:Complex}) = fieldtype(C, 1)
123+
real(::Type{Union{}}, slurp...) = Union{}(im)
123124

124125
"""
125126
isreal(x) -> Bool

base/essentials.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ See also: [`round`](@ref), [`trunc`](@ref), [`oftype`](@ref), [`reinterpret`](@r
311311
function convert end
312312

313313
# ensure this is never ambiguous, and therefore fast for lookup
314-
convert(T::Type{Union{}}, x) = throw(MethodError(convert, (T, x)))
314+
convert(T::Type{Union{}}, x...) = throw(ArgumentError("cannot convert a value to Union{} for assignment"))
315315

316316
convert(::Type{Type}, x::Type) = x # the ssair optimizer is strongly dependent on this method existing to avoid over-specialization
317317
# in the absence of inlining-enabled
@@ -535,6 +535,7 @@ Neither `convert` nor `cconvert` should take a Julia object and turn it into a `
535535
function cconvert end
536536

537537
cconvert(T::Type, x) = x isa T ? x : convert(T, x) # do the conversion eagerly in most cases
538+
cconvert(::Type{Union{}}, x...) = convert(Union{}, x...)
538539
cconvert(::Type{<:Ptr}, x) = x # but defer the conversion to Ptr to unsafe_convert
539540
unsafe_convert(::Type{T}, x::T) where {T} = x # unsafe_convert (like convert) defaults to assuming the convert occurred
540541
unsafe_convert(::Type{T}, x::T) where {T<:Ptr} = x # to resolve ambiguity with the next method

base/float.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ Float64
310310
"""
311311
float(::Type{T}) where {T<:Number} = typeof(float(zero(T)))
312312
float(::Type{T}) where {T<:AbstractFloat} = T
313+
float(::Type{Union{}}, slurp...) = Union{}(0.0)
313314

314315
"""
315316
unsafe_trunc(T, x)

base/generator.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ Base.HasLength()
9292
"""
9393
IteratorSize(x) = IteratorSize(typeof(x))
9494
IteratorSize(::Type) = HasLength() # HasLength is the default
95+
IteratorSize(::Type{Union{}}, slurp...) = throw(ArgumentError("Union{} does not have elements"))
96+
IteratorSize(::Type{Any}) = SizeUnknown()
9597

9698
IteratorSize(::Type{<:Tuple}) = HasLength()
9799
IteratorSize(::Type{<:AbstractArray{<:Any,N}}) where {N} = HasShape{N}()
98100
IteratorSize(::Type{Generator{I,F}}) where {I,F} = IteratorSize(I)
99101

100-
IteratorSize(::Type{Any}) = SizeUnknown()
101-
102102
haslength(iter) = IteratorSize(iter) isa Union{HasShape, HasLength}
103103

104104
abstract type IteratorEltype end
@@ -126,7 +126,7 @@ Base.HasEltype()
126126
"""
127127
IteratorEltype(x) = IteratorEltype(typeof(x))
128128
IteratorEltype(::Type) = HasEltype() # HasEltype is the default
129+
IteratorEltype(::Type{Union{}}, slurp...) = throw(ArgumentError("Union{} does not have elements"))
130+
IteratorEltype(::Type{Any}) = EltypeUnknown()
129131

130132
IteratorEltype(::Type{Generator{I,T}}) where {I,T} = EltypeUnknown()
131-
132-
IteratorEltype(::Type{Any}) = EltypeUnknown()

base/indices.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ particular, [`eachindex`](@ref) creates an iterator whose type depends
9292
on the setting of this trait.
9393
"""
9494
IndexStyle(A::AbstractArray) = IndexStyle(typeof(A))
95-
IndexStyle(::Type{Union{}}) = IndexLinear()
95+
IndexStyle(::Type{Union{}}, slurp...) = IndexLinear()
9696
IndexStyle(::Type{<:AbstractArray}) = IndexCartesian()
9797
IndexStyle(::Type{<:Array}) = IndexLinear()
9898
IndexStyle(::Type{<:AbstractRange}) = IndexLinear()

base/io.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ julia> read(io, String)
219219
```
220220
"""
221221
read(stream, t)
222+
read(stream, ::Type{Union{}}, slurp...; kwargs...) = error("cannot read a value of type Union{}")
223+
222224

223225
"""
224226
write(io::IO, x)

base/iterators.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,7 @@ IteratorEltype(::Type{Flatten{Tuple{}}}) = IteratorEltype(Tuple{})
11701170
_flatteneltype(I, ::HasEltype) = IteratorEltype(eltype(I))
11711171
_flatteneltype(I, et) = EltypeUnknown()
11721172

1173+
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{Union{}}, slurp...) = HasLength() # length==0
11731174
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:NTuple{N,Any}}) where {N} = HasLength()
11741175
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Tuple}) = SizeUnknown()
11751176
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Number}) = HasLength()
@@ -1181,6 +1182,7 @@ _flatten_iteratorsize(sz, ::HasEltype, ::Type{Tuple{}}) = HasLength()
11811182

11821183
IteratorSize(::Type{Flatten{I}}) where {I} = _flatten_iteratorsize(IteratorSize(I), IteratorEltype(I), I)
11831184

1185+
flatten_length(f, T::Type{Union{}}, slurp...) = 0
11841186
function flatten_length(f, T::Type{<:NTuple{N,Any}}) where {N}
11851187
return N * length(f.it)
11861188
end

base/missing.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ nonmissingtype(::Type{T}) where {T} = typesplit(T, Missing)
4141
function nonmissingtype_checked(T::Type)
4242
R = nonmissingtype(T)
4343
R >: T && error("could not compute non-missing type")
44+
R <: Union{} && error("cannot convert a value to missing for assignment")
4445
return R
4546
end
4647

@@ -69,7 +70,6 @@ convert(::Type{T}, x::T) where {T>:Union{Missing, Nothing}} = x
6970
convert(::Type{T}, x) where {T>:Missing} = convert(nonmissingtype_checked(T), x)
7071
convert(::Type{T}, x) where {T>:Union{Missing, Nothing}} = convert(nonmissingtype_checked(nonnothingtype_checked(T)), x)
7172

72-
7373
# Comparison operators
7474
==(::Missing, ::Missing) = missing
7575
==(::Missing, ::Any) = missing

base/number.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ julia> zero(rand(2,2))
307307
"""
308308
zero(x::Number) = oftype(x,0)
309309
zero(::Type{T}) where {T<:Number} = convert(T,0)
310+
zero(::Type{Union{}}, slurp...) = Union{}(0)
310311

311312
"""
312313
one(x)
@@ -345,6 +346,7 @@ julia> import Dates; one(Dates.Day(1))
345346
"""
346347
one(::Type{T}) where {T<:Number} = convert(T,1)
347348
one(x::T) where {T<:Number} = one(T)
349+
one(::Type{Union{}}, slurp...) = Union{}(1)
348350
# note that convert(T, 1) should throw an error if T is dimensionful,
349351
# so this fallback definition should be okay.
350352

@@ -368,6 +370,7 @@ julia> import Dates; oneunit(Dates.Day)
368370
"""
369371
oneunit(x::T) where {T} = T(one(x))
370372
oneunit(::Type{T}) where {T} = T(one(T))
373+
oneunit(::Type{Union{}}, slurp...) = Union{}(1)
371374

372375
"""
373376
big(T::Type)
@@ -388,3 +391,4 @@ Complex{BigInt}
388391
```
389392
"""
390393
big(::Type{T}) where {T<:Number} = typeof(big(zero(T)))
394+
big(::Type{Union{}}, slurp...) = Union{}(0)

base/operators.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ julia> widen(1.5f0)
888888
"""
889889
widen(x::T) where {T} = convert(widen(T), x)
890890
widen(x::Type{T}) where {T} = throw(MethodError(widen, (T,)))
891+
widen(x::Type{Union{}}, slurp...) = throw(MethodError(widen, (Union{},)))
891892

892893
# function pipelining
893894

base/parse.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ julia> parse(Complex{Float64}, "3.2e-1 + 4.5im")
3636
```
3737
"""
3838
parse(T::Type, str; base = Int)
39+
parse(::Type{Union{}}, slurp...; kwargs...) = error("cannot parse a value as Union{}")
3940

4041
function parse(::Type{T}, c::AbstractChar; base::Integer = 10) where T<:Integer
4142
a::Int = (base <= 36 ? 10 : 36)
@@ -251,6 +252,7 @@ function parse(::Type{T}, s::AbstractString; base::Union{Nothing,Integer} = noth
251252
convert(T, tryparse_internal(T, s, firstindex(s), lastindex(s),
252253
base===nothing ? 0 : check_valid_base(base), true))
253254
end
255+
tryparse(::Type{Union{}}, slurp...; kwargs...) = error("cannot parse a value as Union{}")
254256

255257
## string to float functions ##
256258

base/promotion.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,12 @@ it for new types as appropriate.
323323
function promote_rule end
324324

325325
promote_rule(::Type, ::Type) = Bottom
326+
# Define some methods to avoid needing to enumerate unrelated possibilities when presented
327+
# with Type{<:T}, and return a value in general accordance with the result given by promote_type
328+
promote_rule(::Type{Bottom}, slurp...) = Bottom
329+
promote_rule(::Type{Bottom}, ::Type{Bottom}, slurp...) = Bottom # not strictly necessary, since the next method would match unambiguously anyways
330+
promote_rule(::Type{Bottom}, ::Type{T}, slurp...) where {T} = T
331+
promote_rule(::Type{T}, ::Type{Bottom}, slurp...) where {T} = T
326332

327333
promote_result(::Type,::Type,::Type{T},::Type{S}) where {T,S} = (@inline; promote_type(T,S))
328334
# If no promote_rule is defined, both directions give Bottom. In that

base/some.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ end
2929
function nonnothingtype_checked(T::Type)
3030
R = nonnothingtype(T)
3131
R >: T && error("could not compute non-nothing type")
32+
R <: Union{} && error("cannot convert a value to nothing for assignment")
3233
return R
3334
end
3435

base/traits.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ OrderStyle(::Type{<:Real}) = Ordered()
1111
OrderStyle(::Type{<:AbstractString}) = Ordered()
1212
OrderStyle(::Type{Symbol}) = Ordered()
1313
OrderStyle(::Type{<:Any}) = Unordered()
14-
OrderStyle(::Type{Union{}}) = Ordered()
14+
OrderStyle(::Type{Union{}}, slurp...) = Ordered()
1515

1616
# trait for objects that support arithmetic
1717
abstract type ArithmeticStyle end
@@ -23,6 +23,7 @@ ArithmeticStyle(instance) = ArithmeticStyle(typeof(instance))
2323
ArithmeticStyle(::Type{<:AbstractFloat}) = ArithmeticRounds()
2424
ArithmeticStyle(::Type{<:Integer}) = ArithmeticWraps()
2525
ArithmeticStyle(::Type{<:Any}) = ArithmeticUnknown()
26+
ArithmeticStyle(::Type{Union{}}, slurp...) = ArithmeticUnknown()
2627

2728
# trait for objects that support ranges with regular step
2829
"""
@@ -58,5 +59,6 @@ ranges with an element type which is a subtype of `Integer`.
5859
abstract type RangeStepStyle end
5960
struct RangeStepRegular <: RangeStepStyle end # range with regular step
6061
struct RangeStepIrregular <: RangeStepStyle end # range with rounding error
62+
RangeStepStyle(::Type{Union{}}, slurp...) = RangeStepIrregular()
6163

6264
RangeStepStyle(instance) = RangeStepStyle(typeof(instance))

src/gf.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,8 @@ static int get_intersect_visitor(jl_typemap_entry_t *oldentry, struct typemap_in
14481448
// skip if no world has both active
14491449
// also be careful not to try to scan something from the current dump-reload though
14501450
return 1;
1451+
// don't need to consider other similar methods if this oldentry will always fully intersect with them and dominates all of them
1452+
typemap_slurp_search(oldentry, &closure->match);
14511453
jl_method_t *oldmethod = oldentry->func.method;
14521454
if (closure->match.issubty // e.g. jl_subtype(closure->newentry.sig, oldentry->sig)
14531455
&& jl_subtype(oldmethod->sig, (jl_value_t*)closure->newentry->sig)) { // e.g. jl_type_equal(closure->newentry->sig, oldentry->sig)
@@ -1472,7 +1474,7 @@ static jl_value_t *get_intersect_matches(jl_typemap_t *defs, jl_typemap_entry_t
14721474
else
14731475
va = NULL;
14741476
}
1475-
struct matches_env env = {{get_intersect_visitor, (jl_value_t*)type, va,
1477+
struct matches_env env = {{get_intersect_visitor, (jl_value_t*)type, va, /* .search_slurp = */ 0,
14761478
/* .ti = */ NULL, /* .env = */ jl_emptysvec, /* .issubty = */ 0},
14771479
/* .newentry = */ newentry, /* .shadowed */ NULL, /* .replaced */ NULL};
14781480
JL_GC_PUSH3(&env.match.env, &env.match.ti, &env.shadowed);
@@ -3149,6 +3151,7 @@ struct ml_matches_env {
31493151
int intersections;
31503152
size_t world;
31513153
int lim;
3154+
int include_ambiguous;
31523155
// results:
31533156
jl_value_t *t; // array of method matches
31543157
size_t min_valid;
@@ -3204,6 +3207,9 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio
32043207
return 0;
32053208
closure->lim--;
32063209
}
3210+
// don't need to consider other similar methods if this ml will always fully intersect with them and dominates all of them
3211+
if (!closure->include_ambiguous || closure->lim != -1)
3212+
typemap_slurp_search(ml, &closure->match);
32073213
closure->matc = make_method_match((jl_tupletype_t*)closure->match.ti,
32083214
closure->match.env, meth,
32093215
closure->match.issubty ? FULLY_COVERS : NOT_FULLY_COVERS);
@@ -3253,9 +3259,9 @@ static jl_value_t *ml_matches(jl_methtable_t *mt,
32533259
else
32543260
va = NULL;
32553261
}
3256-
struct ml_matches_env env = {{ml_matches_visitor, (jl_value_t*)type, va,
3262+
struct ml_matches_env env = {{ml_matches_visitor, (jl_value_t*)type, va, /* .search_slurp = */ 0,
32573263
/* .ti = */ NULL, /* .env = */ jl_emptysvec, /* .issubty = */ 0},
3258-
intersections, world, lim, /* .t = */ jl_an_empty_vec_any,
3264+
intersections, world, lim, include_ambiguous, /* .t = */ jl_an_empty_vec_any,
32593265
/* .min_valid = */ *min_valid, /* .max_valid = */ *max_valid, /* .matc = */ NULL};
32603266
struct jl_typemap_assoc search = {(jl_value_t*)type, world, jl_emptysvec, 1, ~(size_t)0};
32613267
jl_value_t *isect2 = NULL;

src/julia_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,12 +1459,14 @@ struct typemap_intersection_env {
14591459
jl_typemap_intersection_visitor_fptr const fptr; // fptr to call on a match
14601460
jl_value_t *const type; // type to match
14611461
jl_value_t *const va; // the tparam0 for the vararg in type, if applicable (or NULL)
1462+
size_t search_slurp;
14621463
// output values
14631464
jl_value_t *ti; // intersection type
14641465
jl_svec_t *env; // intersection env (initialize to null to perform intersection without an environment)
14651466
int issubty; // if `a <: b` is true in `intersect(a,b)`
14661467
};
14671468
int jl_typemap_intersection_visitor(jl_typemap_t *a, int offs, struct typemap_intersection_env *closure);
1469+
void typemap_slurp_search(jl_typemap_entry_t *ml, struct typemap_intersection_env *closure);
14681470

14691471
// -- simplevector.c -- //
14701472

0 commit comments

Comments
 (0)