@@ -297,6 +297,57 @@ end # !HAS_INTEGRATED_CACHE
297
297
298
298
Base. Experimental. @MethodTable (GLOBAL_METHOD_TABLE)
299
299
300
+ # Implements a priority lookup for method tables, where the first match in the stack get's returned.
301
+ # An alternative to this would be to use a "Union" where we would query the parent method table and
302
+ # do a most-specific match.
303
+ struct StackedMethodTable{MTV<: CC.MethodTableView } <: CC.MethodTableView
304
+ world:: UInt
305
+ mt:: Core.MethodTable
306
+ parent:: MTV
307
+ end
308
+ StackedMethodTable (world:: UInt , mt:: Core.MethodTable ) = StackedMethodTable (world, mt, CC. InternalMethodTable (world))
309
+ StackedMethodTable (world:: UInt , mt:: Core.MethodTable , parent:: Core.MethodTable ) = StackedMethodTable (world, mt, StackedMethodTable (world, parent))
310
+
311
+ function findall (@nospecialize (sig:: Type ), table:: StackedMethodTable ; limit:: Int = - 1 )
312
+ result = CC. _findall (sig, table. mt, table. world, limit)
313
+ result === nothing && return nothing # to many matches
314
+ nr = CC. length (result)
315
+ if nr ≥ 1 && CC. getindex (result, nr). fully_covers
316
+ # no need to fall back to the parent method view
317
+ return CC. MethodMatchResult (result, true )
318
+ end
319
+
320
+ parent_result = CC. findall (sig, table. parent; limit):: Union{Nothing, CC.MethodMatchResult}
321
+ parent_result === nothing && return nothing # too many matches
322
+
323
+ overlayed = parent_result. overlayed | ! CC. isempty (result)
324
+ parent_result = parent_result. matches:: CC.MethodLookupResult
325
+
326
+ # merge the parent match results with the internal method table
327
+ return CC. MethodMatchResult (
328
+ CC. MethodLookupResult (
329
+ CC. vcat (result. matches, parent_result. matches),
330
+ CC. WorldRange (
331
+ CC. max (result. valid_worlds. min_world, parent_result. valid_worlds. min_world),
332
+ CC. min (result. valid_worlds. max_world, parent_result. valid_worlds. max_world)),
333
+ result. ambig | parent_result. ambig),
334
+ overlayed)
335
+ end
336
+
337
+ CC. isoverlayed (:: StackedMethodTable ) = true
338
+
339
+ function CC. findsup (@nospecialize (sig:: Type ), table:: StackedMethodTable )
340
+ match, valid_worlds = CC. _findsup (sig, table. mt, table. world)
341
+ match != = nothing && return match, valid_worlds, true
342
+ # look up in parent
343
+ parent_match, parent_valid_worlds, overlayed = CC. findsup (sig, table. parent)
344
+ return (
345
+ parent_match,
346
+ CC. WorldRange (
347
+ max (valid_worlds. min_world, parent_valid_worlds. min_world),
348
+ min (valid_worlds. max_world, parent_valid_worlds. max_world)),
349
+ overlayed)
350
+ end
300
351
301
352
# # interpreter
302
353
0 commit comments