Open p6rt opened 7 years ago
Mu provides iterator method, but when you mix in a role that wants it implemented, it doesn't find it:
m: role Meow { method iterator {…} }; class Bar does Meow {}
camelia rakudo-moar 2a8d1e: OUTPUT: «5===SORRY!5=== Error while compiling \
Yet it all works fine if you are also doing `is SomethingUnrelated`:
m: class Foo { method x {} }; role Meow { method iterator {…} }; class Bar is Foo does Meow {} camelia rakudo-moar 2a8d1e: ( no output )
On Thu, 29 Jun 2017 03:46:02 -0700, cpan@zoffix.com wrote:
Mu provides iterator method, but when you mix in a role that wants it implemented, it doesn't find it:
m: role Meow { method iterator {…} }; class Bar does Meow {} camelia rakudo-moar 2a8d1e: OUTPUT: «5===SORRY!5=== Error while compiling \
â¤Method 'iterator' must be implemented by Bar because it is required by roles: Meow.â¤at \ :1â¤Â» Yet it all works fine if you are also doing `is SomethingUnrelated`:
m: class Foo { method x {} }; role Meow { method iterator {…} }; class Bar is Foo does Meow {} camelia rakudo-moar 2a8d1e: ( no output )
Another example turned up; fails to notice the method is provided by `handles`:
class HTTP::Header does Associative does Iterable { subset StrOrArrayOfStr where Str | ( Array & {.all ~~ Str} );
has %!fields of StrOrArrayOfStr handles \<AT-KEY EXISTS-KEY DELETE-KEY push iterator list kv keys values>;
method Str { #`[not shown, for brevity] } }
This is from https://github.com/perl6/doc/issues/1438
On Mon, 07 Aug 2017 08:25:10 -0700, cpan@zoffix.com wrote:
On Thu, 29 Jun 2017 03:46:02 -0700, cpan@zoffix.com wrote:
Mu provides iterator method, but when you mix in a role that wants it implemented, it doesn't find it:
m: role Meow { method iterator {…} }; class Bar does Meow {} camelia rakudo-moar 2a8d1e: OUTPUT: «5===SORRY!5=== Error while compiling \
â¤Method 'iterator' must be implemented by Bar because it is required by roles: Meow.â¤at \ :1â¤Â» Yet it all works fine if you are also doing `is SomethingUnrelated`:
m: class Foo { method x {} }; role Meow { method iterator {…} }; class Bar is Foo does Meow {} camelia rakudo-moar 2a8d1e: ( no output )
Another example turned up; fails to notice the method is provided by `handles`:
class HTTP::Header does Associative does Iterable { subset StrOrArrayOfStr where Str | ( Array & {.all ~~ Str} );
has %!fields of StrOrArrayOfStr handles \<AT-KEY EXISTS-KEY DELETE-KEY push iterator list kv keys values>;
method Str { #`[not shown, for brevity] } }
This is from https://github.com/perl6/doc/issues/1438
I've traced this as far back as RoleToClassApplier.has_method not getting anything in .^mro except itself... unless there is an "is", in which case it gets the inherited class.
It will then get Any/Mu thereby. Unless that "is" was an "is Mu" in which case it only gets Mu:
# This fails... .elems is from Any and compute_mro recurses # into the type in the "is". perl6 -e 'role Meow { method elems {...} }; class Boo { }; class Bar is Mu does Meow { }; Bar.^mro.say'
It looks like with a not-yet-composed class C3MRI.compute_mro will not find Any/Mu... it is not the case that comput_mro was called even earlier than this and cached an incomplete $!mro. There must be a fixup to prevent this situation because:
$ perl6 -e 'role Meow { method split {...} }; class Boo { }; class Bar does Meow { method split { 42 } }; Bar.^mro.say' ((Bar) (Any) (Mu))
...the code in C3MRO if left to its own devices would have left Bar with only itself in .^mro in this situation.
Tracing it back up, if you look several lines under the call to RoleToClassApplier.apply, you'll see the code that adds .get_default_parent_type to the mro. I'm too tired to try at the moment, but either this needs to be done earlier, or we need to emulate it in RoleToClassApplier.
The RT System itself - Status changed from 'new' to 'open'
On Mon, 07 Aug 2017 08:25:10 -0700, cpan@zoffix.com wrote:
On Thu, 29 Jun 2017 03:46:02 -0700, cpan@zoffix.com wrote:
Mu provides iterator method, but when you mix in a role that wants it implemented, it doesn't find it:
m: role Meow { method iterator {…} }; class Bar does Meow {} camelia rakudo-moar 2a8d1e: OUTPUT: «5===SORRY!5=== Error while compiling \
â¤Method 'iterator' must be implemented by Bar because it is required by roles: Meow.â¤at \ :1â¤Â» Yet it all works fine if you are also doing `is SomethingUnrelated`:
m: class Foo { method x {} }; role Meow { method iterator {…} }; class Bar is Foo does Meow {} camelia rakudo-moar 2a8d1e: ( no output )
Another example turned up; fails to notice the method is provided by `handles`:
class HTTP::Header does Associative does Iterable { subset StrOrArrayOfStr where Str | ( Array & {.all ~~ Str} );
has %!fields of StrOrArrayOfStr handles \<AT-KEY EXISTS-KEY DELETE-KEY push iterator list kv keys values>;
method Str { #`[not shown, for brevity] } }
This is from https://github.com/perl6/doc/issues/1438
Rakudo PR request 1170 submitted to address this.
With that patch applied both above examples work and this still fails, as it should:
$ perl6 -e 'class Foo { method x {} }; role Meow { method elems {…} }; class Bar is Mu does Meow {}' ===SORRY!=== Error while compiling -e Method 'elems' must be implemented by Bar because it is required by roles: Meow. at -e:1
As a status update: The code from the original post doesn't die anymore (and neither does the code from the first response).
$ ./rakudo-m -e 'role Meow { method iterator {...} }; class Bar does Meow {}; say "alive"'
alive
And the evaluation from the last response, which is supposed to die, dies:
$ ./rakudo-m -e 'class Foo { method x {} }; role Meow { method elems {...} }; class Bar is Mu does Meow {}'
===SORRY!=== Error while compiling -e
Method 'elems' must be implemented by Bar because it is required by roles: Meow.
at -e:1
So, it looks like this could be closed. But we should check if this is covered by tests.
Migrated from rt.perl.org#131676 (status was 'open')
Searchable as RT131676$