Skip to content

Commit 0a4a850

Browse files
committed
follow up #44448, correct findall/findsup for OverlayMethodTable (#44511)
- respect world range of failed lookup into `OverlayMethodTable`: <#44448 (comment)> - fix calculation of merged valid world range: <#44448 (comment)> - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: <#44448 (comment)> - fix the default `limit::Int` value of `findall`
1 parent d15704a commit 0a4a850

File tree

3 files changed

+31
-28
lines changed

3 files changed

+31
-28
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,11 +1474,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
14741474
types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
14751475
nargtype = Tuple{ft, nargtype.parameters...}
14761476
argtype = Tuple{ft, argtype.parameters...}
1477-
result = findsup(types, method_table(interp))
1478-
result === nothing && return CallMeta(Any, false)
1479-
match, valid_worlds = result
1480-
method = match.method
1477+
match, valid_worlds = findsup(types, method_table(interp))
1478+
match === nothing && return CallMeta(Any, false)
14811479
update_valid_age!(sv, valid_worlds)
1480+
method = match.method
14821481
(ti, env::SimpleVector) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
14831482
(; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv)
14841483
edge !== nothing && add_backedge!(edge::MethodInstance, sv)

base/compiler/methodtable.jl

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,28 @@ given signature `sig`. If no applicable methods are found, an empty result is
4747
returned. If the number of applicable methods exceeded the specified limit,
4848
`missing` is returned.
4949
"""
50-
function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=typemax(Int))
50+
function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=Int(typemax(Int32)))
5151
return _findall(sig, nothing, table.world, limit)
5252
end
5353

54-
function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=typemax(Int))
54+
function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=Int(typemax(Int32)))
5555
result = _findall(sig, table.mt, table.world, limit)
5656
result === missing && return missing
57-
if !isempty(result)
58-
if all(match->match.fully_covers, result)
59-
# no need to fall back to the internal method table
60-
return result
61-
else
62-
# merge the match results with the internal method table
63-
fallback_result = _findall(sig, nothing, table.world, limit)
64-
return MethodLookupResult(
65-
vcat(result.matches, fallback_result.matches),
66-
WorldRange(min(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world),
67-
max(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)),
68-
result.ambig | fallback_result.ambig)
69-
end
57+
nr = length(result)
58+
if nr 1 && result[nr].fully_covers
59+
# no need to fall back to the internal method table
60+
return result
7061
end
7162
# fall back to the internal method table
72-
return _findall(sig, nothing, table.world, limit)
63+
fallback_result = _findall(sig, nothing, table.world, limit)
64+
fallback_result === missing && return missing
65+
# merge the fallback match results with the internal method table
66+
return MethodLookupResult(
67+
vcat(result.matches, fallback_result.matches),
68+
WorldRange(
69+
max(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world),
70+
min(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)),
71+
result.ambig | fallback_result.ambig)
7372
end
7473

7574
function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt, limit::Int)
@@ -102,17 +101,22 @@ function findsup(@nospecialize(sig::Type), table::InternalMethodTable)
102101
end
103102

104103
function findsup(@nospecialize(sig::Type), table::OverlayMethodTable)
105-
result = _findsup(sig, table.mt, table.world)
106-
result === nothing || return result
107-
return _findsup(sig, nothing, table.world) # fall back to the internal method table
104+
match, valid_worlds = _findsup(sig, table.mt, table.world)
105+
match !== nothing && return match, valid_worlds
106+
# fall back to the internal method table
107+
fallback_match, fallback_valid_worlds = _findsup(sig, nothing, table.world)
108+
return fallback_match, WorldRange(
109+
max(valid_worlds.min_world, fallback_valid_worlds.min_world),
110+
min(valid_worlds.max_world, fallback_valid_worlds.max_world))
108111
end
109112

110113
function _findsup(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt)
111114
min_valid = RefValue{UInt}(typemin(UInt))
112115
max_valid = RefValue{UInt}(typemax(UInt))
113-
result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}),
116+
match = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}),
114117
sig, mt, world, min_valid, max_valid)::Union{MethodMatch, Nothing}
115-
return result === nothing ? result : (result, WorldRange(min_valid[], max_valid[]))
118+
valid_worlds = WorldRange(min_valid[], max_valid[])
119+
return match, valid_worlds
116120
end
117121

118122
isoverlayed(::MethodTableView) = error("unsatisfied MethodTableView interface")

base/reflection.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,11 +1347,11 @@ end
13471347
print_statement_costs(args...; kwargs...) = print_statement_costs(stdout, args...; kwargs...)
13481348

13491349
function _which(@nospecialize(tt::Type), world=get_world_counter())
1350-
result = Core.Compiler._findsup(tt, nothing, world)
1351-
if result === nothing
1350+
match, _ = Core.Compiler._findsup(tt, nothing, world)
1351+
if match === nothing
13521352
error("no unique matching method found for the specified argument types")
13531353
end
1354-
return first(result)::Core.MethodMatch
1354+
return match
13551355
end
13561356

13571357
"""

0 commit comments

Comments
 (0)