Skip to content

Instantly share code, notes, and snippets.

@ab5tract
Last active August 26, 2024 15:56
Show Gist options
  • Save ab5tract/6bf842c703c1d2c8817561f4cbf5e601 to your computer and use it in GitHub Desktop.
Save ab5tract/6bf842c703c1d2c8817561f4cbf5e601 to your computer and use it in GitHub Desktop.
trait_mod:<is> weirdness
diff --git a/src/Perl6/Actions.nqp b/src/Perl6/Actions.nqp
index c80a941bb..f67a79888 100644
--- a/src/Perl6/Actions.nqp
+++ b/src/Perl6/Actions.nqp
@@ -6064,6 +6064,9 @@ class Perl6::Actions is HLL::Actions does STDActions {
}
method apply($declarand, *%additional) {
+ if $!match<longname> eq 'revision-gated' {
+ try dd($!trait_mod, $!match, $declarand);
+ }
$*W.apply_trait($!match, $!trait_mod, $declarand, |@!pos_args,
|%!named_args, |%additional);
}
diff --git a/src/core.c/Array.rakumod b/src/core.c/Array.rakumod
index 59a22f98e..2a0abc10b 100644
--- a/src/core.c/Array.rakumod
+++ b/src/core.c/Array.rakumod
@@ -909,6 +909,8 @@ my class Array { # declared in BOOTSTRAP
my $empty := nqp::create(IterationBuffer); # splicing in without values
#------ splice() candidates
+# proto method splice(Array:D: |) {*}
+# proto method splice(Array:D: |) is revision-gated("6.e") {*}
multi method splice(Array:D \SELF: --> Array:D) {
nqp::if(
nqp::isconcrete(nqp::getattr(SELF,List,'$!reified')),
@@ -1097,8 +1099,8 @@ my class Array { # declared in BOOTSTRAP
:range("0..^{self.elems - $offset}")
).throw
}
- #------ splice(offset,size,array) candidates
+ #------ splice(offset,size,array) candidates
# we have these 9 multies to avoid infiniloop when incorrect types are
# given to $offset/$size. Other attempts to resolve this showed 30%+
# performance decreases
@@ -1153,26 +1155,26 @@ my class Array { # declared in BOOTSTRAP
# without flattening its contents like in the default behavior
multi method splice(Array:D:
Whatever $, Whatever $, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
self.splice(self.elems,0,[$@new])
}
multi method splice(Array:D:
Whatever $, Int:D $size, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
self.splice(self.elems,$size,[$@new])
}
multi method splice(Array:D:
Whatever $, Callable:D $size, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
my int $elems = self.elems;
self.splice($elems,$size(nqp::sub_i($elems,$elems)),[$@new])
}
multi method splice(Array:D:
Callable:D $offset, Callable:D $size, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
my int $elems = self.elems;
my int $from = $offset($elems);
@@ -1180,7 +1182,7 @@ my class Array { # declared in BOOTSTRAP
}
multi method splice(Array:D:
Callable:D $offset, Whatever $, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
my int $elems = self.elems;
my int $from = $offset($elems);
@@ -1188,25 +1190,25 @@ my class Array { # declared in BOOTSTRAP
}
multi method splice(Array:D:
Callable:D $offset, Int:D $size, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
self.splice($offset(self.elems),$size,[$@new])
}
multi method splice(Array:D:
Int:D $offset, Whatever $, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
self.splice($offset,self.elems - $offset,[$@new])
}
multi method splice(Array:D:
Int:D $offset, Callable:D $size, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
self.splice($offset,$size(self.elems - $offset),[$@new])
}
multi method splice(Array:D:
Int:D $offset, Int:D $size, @new is item
- --> Array:D)
+ --> Array:D) is revision-gated("6.e")
{
self.splice($offset,$size,[$@new])
}
diff --git a/src/core.c/Routine.rakumod b/src/core.c/Routine.rakumod
index ebba91e3b..7edf87f36 100644
--- a/src/core.c/Routine.rakumod
+++ b/src/core.c/Routine.rakumod
@@ -423,4 +423,20 @@ multi sub trait_mod:<is>(Routine:D $r, :%prec! --> Nil) {
)
}
+#role RevisionGated
+#[
+# Str $version,
+# Version $ver = Version.new($version),
+# Int $internal-revision = +(Version.new("6.c").parts[*-1] .. $ver.parts[*-1])
+#]
+#{
+# method REVISION-GATED(--> Bool) { True }
+# method REQUIRED-REVISION(--> Int) { $internal-revision }
+# method CUSTOM-DISPATCHER(--> Str) { '' }
+#}
+#
+#multi sub trait_mod:<is>(Routine:D $r, Str :$revistion-gated! --> Nil) {
+# $r does RevisionGated[$revistion-gated]
+#}
+
# vim: expandtab shiftwidth=4
diff --git a/src/core.c/traits.rakumod b/src/core.c/traits.rakumod
index 3a129b922..30a928083 100644
--- a/src/core.c/traits.rakumod
+++ b/src/core.c/traits.rakumod
@@ -178,6 +178,8 @@ multi sub trait_mod:<is>(Routine:D $r, |c) {
sub trait-name(&t) { &t.signature.params[1].named_names[0] }
my %info = :file($?FILE), :line($?LINE), :type<is>, :$subtype,
:declaring($r.^name.split('+').head.lc);
@@ -192,6 +194,18 @@ multi sub trait_mod:<is>(Routine:D $r, |c) {
die X::Comp::Trait::Unknown.new: |%info, :highexpect(@expected) }
}
+multi sub trait_mod:<is>(Routine:D $r, :$revision-gated! --> Nil) {
+# nqp::what($revision-gated).Str;
+# die "revision-gated = " ~ nqp::what($revision-gated).Str;
+# my $gated-version = Version.new("6.e");
+# dd :$r;
+# my $internal-revision = +("c" .. $gated-version.parts[{$_ - 1}]); # "c" is for christmas, of course
+# my $internal-revision := 3;
+# my role RevisinoGated { has $.required-revision; method REQUIRED-REVISION(--> Int) { $!required-revision } }
+# my role RevisinoGated[$required-revision] { method REQUIRED-REVISION(--> Int) { $required-revision } }
+# $r does RevisionGated[$internal-revision];
+ $r.^mixin(role RevisionGated { has $.required-revision = 3; method REQUIRED-REVISION(--> Int) { $!required-revision } }) if $revision-gated;
+}
multi sub trait_mod:<is>(Routine:D $r, :rw($)!) {
$r.set_rw();
}
diff --git a/src/vm/moar/dispatchers.nqp b/src/vm/moar/dispatchers.nqp
index f64dde7d3..810aa4a85 100644
--- a/src/vm/moar/dispatchers.nqp
+++ b/src/vm/moar/dispatchers.nqp
@@ -2214,7 +2214,6 @@ sub raku-multi-plan(
my $need_conc_guard := nqp::list_i;
my @possibles;
my int $candidates-with-itemizable-params;
- my int $v6e-or-greater := nqp::getcomp('Raku').language_revision() >= 3;
my int $done;
my int $cur_idx;
@@ -2229,14 +2228,9 @@ sub raku-multi-plan(
if nqp::isconcrete($cur_candidate) {
# Mark this group for disambigation via is item traits on params
- if nqp::atkey($cur_candidate, 'item_disambiguation') {
- if $v6e-or-greater {
- if ! $candidates-with-itemizable-params {
- $candidates-with-itemizable-params := 1;
- }
- } else {
- next; # skip the item_disambiguation candidate for less than v6.e
- }
+ if !$candidates-with-itemizable-params
+ && nqp::atkey($cur_candidate, 'item_disambiguation') {
+ $candidates-with-itemizable-params := 1;
}
# Candidate; does the arity fit? (If not, it drops out on callsite
@@ -2851,6 +2845,22 @@ nqp::register('raku-multi-core',
my $target := nqp::captureposarg($capture, 0);
my @candidates := $target.dispatch_order;
+# my $revision-gated := nqp::decont(nqp::how_nd($target).find_method(nqp::decont($target), 'REVISION-GATED', :no_fallback));
+# if nqp::getenvhash<WTF> && nqp::isconcrete($revision-gated) && $revision-gated($target) {
+ if nqp::getenvhash<WTF> {
+ my int $idx := 0;
+ my @allowed-candidates;
+ while $idx < nqp::elems(@candidates) {
+ my $candidate := nqp::atpos(@candidates, $idx);
+ my $revision-required := nqp::decont(nqp::how_nd($candidate).find_method(nqp::decont($candidate), 'REQUIRED-REVISION', :no_fallback));
+ if ! nqp::isconcrete($revision-required) || (nqp::isconcrete($revision-required) && $revision-required($candidate) >= nqp::getcomp('Raku').language_revision) {
+ nqp::push(@allowed-candidates, $candidate);
+ }
+ $idx++;
+ }
+ @candidates := @allowed-candidates;
+ }
+
# Drop the first argument, to get just the arguments to dispatch on,
# and then produce a multi-dispatch plan. Decide what to do based
# upon it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment