Skip to content

Commit

Permalink
Ensure that candidates carry itemization reqs
Browse files Browse the repository at this point in the history
Since we already visit all of the parameters here, we
can avoid type and flag checks of these same parameters
in the dispatch code by providing an `item_disambiguation`
flag in the dispatch_info hash that we access later in
the multi dispatch logic.

This is a relatively heavy intervention into the way that
dispatch normally works. It is all to workaround the current
reality of 'callmethod' and 'callstatic' having a bug whereby
the argument passed to ParamTypeCheck is already decont'd.

Since the entire point of `is item` is to dispatch based on
containerization, that's clearly a blocker.

So, in the case of a named parameter with an in `is item` trait
we cannot simply rely on the VM binder to check the candidate's
suitability. Instead we pass the type information of `is item`
named argumants along with the rest of the dispatch_info hash.
  • Loading branch information
ab5tract committed Apr 9, 2024
1 parent 819312c commit d6e8001
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/Perl6/bootstrap.c/BOOTSTRAP.nqp
Original file line number Diff line number Diff line change
Expand Up @@ -3326,6 +3326,7 @@ BEGIN {
my int $num_types;
my @coerce_type_idxs;
my @coerce_type_objs;
my int $item_disambiguation;

my int $n := nqp::elems(@params);
my int $j;
Expand All @@ -3348,7 +3349,7 @@ BEGIN {
}

# For named arguments:
# * Under the legacy dispatcher (not on MoarVM, which uses
# * Under the legacy dispatcher (not on MoarVM, which uses
# new-disp) we leave named argument checking to be done via
# a bind check. We only set that if it's a required named.
# * For the new-disp based dispatcher, we collect a list of
Expand Down Expand Up @@ -3391,6 +3392,31 @@ BEGIN {
);
++$k;
}
# we can't use binding in the case of SIG_ELEM_IS_ITEM due
# to a bug that deconts arguments as passed to ParamTypeCheck
# in 'callstatic' and 'callmethod'. instead we do a type check
# of named arguments in the case of ambiguous dispatch.
if $flags +& nqp::const::SIG_ELEM_IS_ITEM {
++$item_disambiguation;
my $named_types := nqp::ifnull(
nqp::atkey(%info, 'named_types'),
nqp::bindkey(%info, 'named_types', nqp::hash)
);
if $flags +& nqp::const::SIG_ELEM_TYPE_GENERIC {
nqp::bindkey(%info, 'bind_check', 1);
nqp::bindkey(%info, 'constrainty', 1);
nqp::bindkey($named_types, nqp::atpos_s($named_names,0), Any);
}
else {
my $ptype := nqp::getattr($param, Parameter, '$!type');
if $ptype.HOW.archetypes($ptype).coercive {
my $ctype := $ptype.HOW.wrappee($ptype, :coercion);
$ptype := $ctype.HOW.constraint_type($ctype);
}
nqp::bindkey($named_types, nqp::atpos_s($named_names,0), $ptype);
}
# TODO: Coercion types ...
}
next;
}

Expand Down Expand Up @@ -3471,6 +3497,15 @@ BEGIN {
)
}

if $flags +& nqp::const::SIG_ELEM_IS_ITEM {
nqp::bindpos_i(
@type_flags,
$significant_param,
nqp::atpos_i(@type_flags, $significant_param) + nqp::const::SIG_ELEM_IS_ITEM
);
++$item_disambiguation;
}

# Keep track of coercion types; they'll need an extra entry
# in the things we sort.
if $param.coercive {
Expand All @@ -3488,6 +3523,9 @@ BEGIN {
nqp::bindkey(%info, 'max_arity', $max_arity);
nqp::bindkey(%info, 'num_types', $num_types);

nqp::bindkey(%info, 'item_disambiguation', 1)
if $item_disambiguation;

if nqp::elems(@coerce_type_idxs) {
nqp::bindkey(%info, 'coerce_type_idxs', @coerce_type_idxs);
nqp::bindkey(%info, 'coerce_type_objs', @coerce_type_objs);
Expand Down

0 comments on commit d6e8001

Please sign in to comment.