From 20a3ed0336031ba9c79935bfdecd45c8d58e5b3a Mon Sep 17 00:00:00 2001 From: Jonathan Worthington Date: Wed, 1 Sep 2021 19:29:38 +0200 Subject: [PATCH] Add Junction failover for named args in multis This makes multiple dispatch failover also account for named arguments, not just positional ones. This is not precisely the same semantics as on the master branch: there, we invoke a candidate that would fail to bind because of an encountered Junction arg, and rely on the single dispatch binder failure to trigger auto-threading. This was only true of Junction named arguments to multis, not of positional ones, and thus rather inconsistent. (It was also certainly an implementation accident rather than carefully considered semantics.) The new semantics do it as a bind failover exclusively. --- src/vm/moar/dispatchers.nqp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vm/moar/dispatchers.nqp b/src/vm/moar/dispatchers.nqp index c8d2ed8d43b..46d33020de5 100644 --- a/src/vm/moar/dispatchers.nqp +++ b/src/vm/moar/dispatchers.nqp @@ -1796,14 +1796,15 @@ sub form-raku-capture($vm-capture) { $raku-capture } sub multi-junction-failover($capture) { - # Take a first pass to see if there's a Junction arg. - my int $num-args := nqp::captureposelems($capture); + # Take a first pass to see if there's a Junction arg (we look at both + # named and positional). + my int $num-args := nqp::dispatch('boot-syscall', 'capture-num-args', $capture); my int $i; my $found-junction; while $i < $num-args { - my int $got-prim := nqp::captureposprimspec($capture, $i); + my int $got-prim := nqp::dispatch('boot-syscall', 'capture-arg-prim-spec', $capture, $i); if $got-prim == 0 { - my $value := nqp::captureposarg($capture, $i); + my $value := nqp::dispatch('boot-syscall', 'capture-arg-value', $capture, $i); if nqp::isconcrete($value) && nqp::istype($value, Junction) { $found-junction := 1; last; @@ -1813,12 +1814,12 @@ sub multi-junction-failover($capture) { } # If there is a Junction arg, then take another pass through to put type - # guards on all positional argument types. + # guards on all argument types. if $found-junction { $i := 0; while $i < $num-args { - if nqp::captureposprimspec($capture, $i) == 0 { - my $arg := nqp::captureposarg($capture, $i); + if nqp::dispatch('boot-syscall', 'capture-arg-prim-spec', $capture, $i) == 0 { + my $arg := nqp::dispatch('boot-syscall', 'capture-arg-value', $capture, $i); my $tracked := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, $i); if nqp::istype_nd($arg, Scalar) {