Skip to content

Commit 04f6c8f

Browse files
committed
make ml_matches return nothing when there are too many matches
Continuation from <#44448 (comment)>. Previously `ml_matches` (and its dependent utilities like `_methods_by_ftype`) returned `false` for cases when there are too many matching method, but its consumer like `findall(::Type, ::InternalMethodTable)` usually handles such case as `missing`. This commit does a refactor so that they all use the more consistent value `nothing` for representing that case.
1 parent 1badb9d commit 04f6c8f

File tree

7 files changed

+25
-27
lines changed

7 files changed

+25
-27
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ function find_matching_methods(argtypes::Vector{Any}, @nospecialize(atype), meth
294294
mt === nothing && return FailedMethodMatch("Could not identify method table for call")
295295
mt = mt::Core.MethodTable
296296
result = findall(sig_n, method_table; limit = max_methods)
297-
if result === missing
297+
if result === nothing
298298
return FailedMethodMatch("For one of the union split cases, too many methods matched")
299299
end
300300
(; matches, overlayed) = result
@@ -333,7 +333,7 @@ function find_matching_methods(argtypes::Vector{Any}, @nospecialize(atype), meth
333333
end
334334
mt = mt::Core.MethodTable
335335
result = findall(atype, method_table; limit = max_methods)
336-
if result === missing
336+
if result === nothing
337337
# this means too many methods matched
338338
# (assume this will always be true, so we don't compute / update valid age in this case)
339339
return FailedMethodMatch("Too many methods matched")

base/compiler/bootstrap.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ let interp = NativeInterpreter()
3636
else
3737
tt = Tuple{typeof(f), Vararg{Any}}
3838
end
39-
for m in _methods_by_ftype(tt, 10, typemax(UInt))
39+
for m in _methods_by_ftype(tt, 10, typemax(UInt))::Vector
4040
# remove any TypeVars from the intersection
41+
m = m::MethodMatch
4142
typ = Any[m.spec_types.parameters...]
4243
for i = 1:length(typ)
4344
typ[i] = unwraptv(typ[i])

base/compiler/methodtable.jl

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,38 +57,38 @@ Overlays another method table view with an additional local fast path cache that
5757
can respond to repeated, identical queries faster than the original method table.
5858
"""
5959
struct CachedMethodTable{T} <: MethodTableView
60-
cache::IdDict{MethodMatchKey, Union{Missing,MethodMatchResult}}
60+
cache::IdDict{MethodMatchKey, Union{Nothing,MethodMatchResult}}
6161
table::T
6262
end
63-
CachedMethodTable(table::T) where T = CachedMethodTable{T}(IdDict{MethodMatchKey, Union{Missing,MethodMatchResult}}(), table)
63+
CachedMethodTable(table::T) where T = CachedMethodTable{T}(IdDict{MethodMatchKey, Union{Nothing,MethodMatchResult}}(), table)
6464

6565
"""
6666
findall(sig::Type, view::MethodTableView; limit::Int=-1) ->
67-
MethodMatchResult(matches::MethodLookupResult, overlayed::Bool) or missing
67+
MethodMatchResult(matches::MethodLookupResult, overlayed::Bool) or nothing
6868
6969
Find all methods in the given method table `view` that are applicable to the given signature `sig`.
7070
If no applicable methods are found, an empty result is returned.
71-
If the number of applicable methods exceeded the specified `limit`, `missing` is returned.
71+
If the number of applicable methods exceeded the specified `limit`, `nothing` is returned.
7272
Note that the default setting `limit=-1` does not limit the number of applicable methods.
7373
`overlayed` indicates if any of the matching methods comes from an overlayed method table.
7474
"""
7575
function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=-1)
7676
result = _findall(sig, nothing, table.world, limit)
77-
result === missing && return missing
77+
result === nothing && return nothing
7878
return MethodMatchResult(result, false)
7979
end
8080

8181
function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=-1)
8282
result = _findall(sig, table.mt, table.world, limit)
83-
result === missing && return missing
83+
result === nothing && return nothing
8484
nr = length(result)
8585
if nr 1 && result[nr].fully_covers
8686
# no need to fall back to the internal method table
8787
return MethodMatchResult(result, true)
8888
end
8989
# fall back to the internal method table
9090
fallback_result = _findall(sig, nothing, table.world, limit)
91-
fallback_result === missing && return missing
91+
fallback_result === nothing && return nothing
9292
# merge the fallback match results with the internal method table
9393
return MethodMatchResult(
9494
MethodLookupResult(
@@ -105,10 +105,8 @@ function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable},
105105
_max_val = RefValue{UInt}(typemax(UInt))
106106
_ambig = RefValue{Int32}(0)
107107
ms = _methods_by_ftype(sig, mt, limit, world, false, _min_val, _max_val, _ambig)
108-
if ms === false
109-
return missing
110-
end
111-
return MethodLookupResult(ms::Vector{Any}, WorldRange(_min_val[], _max_val[]), _ambig[] != 0)
108+
isa(ms, Vector) || return nothing
109+
return MethodLookupResult(ms, WorldRange(_min_val[], _max_val[]), _ambig[] != 0)
112110
end
113111

114112
function findall(@nospecialize(sig::Type), table::CachedMethodTable; limit::Int=-1)

base/reflection.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ function _methods_by_ftype(@nospecialize(t), mt::Union{Core.MethodTable, Nothing
950950
return _methods_by_ftype(t, mt, lim, world, false, RefValue{UInt}(typemin(UInt)), RefValue{UInt}(typemax(UInt)), Ptr{Int32}(C_NULL))
951951
end
952952
function _methods_by_ftype(@nospecialize(t), mt::Union{Core.MethodTable, Nothing}, lim::Int, world::UInt, ambig::Bool, min::Ref{UInt}, max::Ref{UInt}, has_ambig::Ref{Int32})
953-
return ccall(:jl_matching_methods, Any, (Any, Any, Cint, Cint, UInt, Ptr{UInt}, Ptr{UInt}, Ptr{Int32}), t, mt, lim, ambig, world, min, max, has_ambig)::Union{Array{Any,1}, Bool}
953+
return ccall(:jl_matching_methods, Any, (Any, Any, Cint, Cint, UInt, Ptr{UInt}, Ptr{UInt}, Ptr{Int32}), t, mt, lim, ambig, world, min, max, has_ambig)::Union{Vector{Any},Nothing}
954954
end
955955

956956
# high-level, more convenient method lookup functions

src/dump.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,7 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets)
13981398
int ambig = 0;
13991399
matches = jl_matching_methods((jl_tupletype_t*)sig, jl_nothing,
14001400
-1, 0, world, &min_valid, &max_valid, &ambig);
1401-
if (matches == jl_false) {
1401+
if (matches == jl_nothing) {
14021402
callee_ids = NULL; // invalid
14031403
break;
14041404
}
@@ -2408,7 +2408,7 @@ static jl_array_t *jl_verify_edges(jl_array_t *targets)
24082408
// TODO: possibly need to included ambiguities too (for the optimizer correctness)?
24092409
matches = jl_matching_methods((jl_tupletype_t*)sig, jl_nothing,
24102410
-1, 0, world, &min_valid, &max_valid, &ambig);
2411-
if (matches == jl_false) {
2411+
if (matches == jl_nothing) {
24122412
valid = 0;
24132413
}
24142414
else {

src/gf.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ static jl_method_instance_t *cache_method(
11021102
size_t max_valid2 = ~(size_t)0;
11031103
temp = ml_matches(mt, compilationsig, MAX_UNSPECIALIZED_CONFLICTS, 1, 1, world, 0, &min_valid2, &max_valid2, NULL);
11041104
int guards = 0;
1105-
if (temp == jl_false) {
1105+
if (temp == jl_nothing) {
11061106
cache_with_orig = 1;
11071107
}
11081108
else {
@@ -2304,7 +2304,7 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES
23042304
*min_valid = min_valid2;
23052305
if (*max_valid > max_valid2)
23062306
*max_valid = max_valid2;
2307-
if (matches == jl_false || jl_array_len(matches) != 1 || ambig)
2307+
if (matches == jl_nothing || jl_array_len(matches) != 1 || ambig)
23082308
return NULL;
23092309
JL_GC_PUSH1(&matches);
23102310
jl_method_match_t *match = (jl_method_match_t*)jl_array_ptr_ref(matches, 0);
@@ -2716,7 +2716,7 @@ static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT
27162716
if (mt == jl_nothing)
27172717
mt = NULL;
27182718
jl_value_t *matches = ml_matches((jl_methtable_t*)mt, (jl_tupletype_t*)types, 1, 0, 0, world, 1, min_valid, max_valid, NULL);
2719-
if (matches == jl_false || jl_array_len(matches) != 1)
2719+
if (matches == jl_nothing || jl_array_len(matches) != 1)
27202720
return NULL;
27212721
jl_method_match_t *matc = (jl_method_match_t*)jl_array_ptr_ref(matches, 0);
27222722
return matc;
@@ -3016,14 +3016,14 @@ static jl_value_t *ml_matches(jl_methtable_t *mt,
30163016
}
30173017
if (!jl_typemap_intersection_visitor(jl_atomic_load_relaxed(&mt->defs), 0, &env.match)) {
30183018
JL_GC_POP();
3019-
return jl_false;
3019+
return jl_nothing;
30203020
}
30213021
}
30223022
else {
30233023
// else: scan everything
30243024
if (!jl_foreach_reachable_mtable(ml_mtable_visitor, &env.match)) {
30253025
JL_GC_POP();
3026-
return jl_false;
3026+
return jl_nothing;
30273027
}
30283028
}
30293029
*min_valid = env.min_valid;
@@ -3105,7 +3105,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt,
31053105
}
31063106
else if (lim == 1) {
31073107
JL_GC_POP();
3108-
return jl_false;
3108+
return jl_nothing;
31093109
}
31103110
}
31113111
else {
@@ -3249,7 +3249,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt,
32493249
ndisjoint += 1;
32503250
if (ndisjoint > lim) {
32513251
JL_GC_POP();
3252-
return jl_false;
3252+
return jl_nothing;
32533253
}
32543254
}
32553255
}
@@ -3396,7 +3396,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt,
33963396
*ambig = has_ambiguity;
33973397
JL_GC_POP();
33983398
if (lim >= 0 && len > lim)
3399-
return jl_false;
3399+
return jl_nothing;
34003400
return env.t;
34013401
}
34023402

stdlib/REPL/src/REPLCompletions.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,9 @@ function complete_methods!(out::Vector{Completion}, @nospecialize(funct), args_e
656656
t_in = Tuple{funct, args_ex...}
657657
m = Base._methods_by_ftype(t_in, nothing, max_method_completions, Base.get_world_counter(),
658658
#=ambig=# true, Ref(typemin(UInt)), Ref(typemax(UInt)), Ptr{Int32}(C_NULL))
659-
if m === false
659+
if !isa(m, Vector)
660660
push!(out, TextCompletion(sprint(Base.show_signature_function, funct) * "( too many methods, use SHIFT-TAB to show )"))
661661
end
662-
m isa Vector || return
663662
for match in m
664663
# TODO: if kwargs_ex, filter out methods without kwargs?
665664
push!(out, MethodCompletion(match.spec_types, match.method))

0 commit comments

Comments
 (0)