On Sun, 28 May 2017 02:31:34 -0700, sml...@gmail.com wrote: > This bug is still present in > > This is Rakudo version 2017.05-272-gfa7aa1c36 built on MoarVM version > 2017.05-25-g62bc54e9 > implementing Perl 6.c.
Not an optimizer problem, still happens with --optimize=0 Here's a history of the rule term:sym<identifier>, which apparently only handles the case of subroutine calls of the form "thing()". We start here many years ago: <identifier> <?[(]> <args> Then we decide we do not want typecasts to fall into this rule: <identifier> <!{ $*W.is_type([~$<identifier>]) }> <?[(]> <args> Then we implement unspace between the name and the parenthesis. <identifier> <!{ $*W.is_type([~$<identifier>]) }> <?before <.unsp>|'('> <args> ...that is a bit tricky... was it intentionally not "<.unsp>? '('"? We'll get into that in a bit. Next we get a commit that does some better error reporting (there's more before and after the part we are watching) <identifier> <!{ $*W.is_type([~$<identifier>]) }> <?before <.unsp>|'('> <![:]> { $pos := $/.pos } <args(1)> ...so, what's that new "<![:]>" for? A ':' cannot happen here due to the "before"... So, let's look at <args>, keeping in mind that it can only happen after "foo\ " or "foo ("... but the unspace or paren in those two forms is part of the string <args> is matching. There's other stuff in it but this is the meat: [ | '(' ~ ')' <semiarglist> | <.unsp> '(' ~ ')' <semiarglist> | [ \s <arglist> ] | <?> ] ...all four cases can hit. Only the first two were hittable before the unspace change... well maybe a malformed semiarglist could get into the fourth one somehow. The unspace change would prevent the third one from being hit... unless there were a way to follow an unspace by a space... but it would be silly to only then accept a single space character there. One wonders what nefarious corner case that covers. The real problem comes with that fourth alternative. We of course need to support calling with no parens for argumentless forms. But that case can fall through to either of term:sym<name> or term:sym<identfier>. Both actions methods seem to be able to handle setting up barename calls. But you can fall through this case to term::sym<identifier> even when there is something else after the unspace which does not resemble an argument list at all. Only term:sym<name> has the ability to handle that. Like, in this ticket, the rest of a postfix method call. That means this: a\ .Str ...is being processed as: (&a()) $_.Str Now, maybe LTM was being leaned on to force that case through term:sym<name>, but perhaps some of the error reporting stuff made some confusing sequenceish points that ruined that. At any rate this weekend I'll submit a patch changing it to: <identifier> <!{ $*W.is_type([~$<identifier>]) }> [ <?before <.unsp>? '('> <?> | \\ <?before '('> ] ...which passes spectest and handles these cases: $ perl6 -e 'my constant \a = 42; say a\ .Str;' 42 $ perl6 -e 'say\(42)' 42 $ perl6 -e 'my constant \a = [1,2]; say a\ [1];' 2 $ perl6 -e 'my constant \a = {:a,:b}; say a\ {"b"};' True $ perl6 -e 'my constant \a = {:a,:b}; say a\ <b>;' True ...and I'll see if I can find out what else to tweak to make this work: $ perl6 -e 'class A { our sub foo ($a) { "OHAI $a".say } }; A::foo\(42)' Too few positionals passed; expected 1 argument but got 0 in sub foo at -e line 1 in block <unit> at -e line 1 ...it looks like this patch breaks the following, but I'm not sure that it should work: $ perl6 -e 'say\ 42' ===SORRY!=== Argument to "say" seems to be malformed ...and these all already worked, but I'll make sure they are tested when I write the tests: $ perl6 -e 'say\ (42)' 42 $ perl6 -e 'my constant \a = [1,2]; say a\[1];' 2 $ perl6 -e 'my constant \a = {:a,:b}; say a\{"b"};' True $ perl6 -e 'my constant \a = {:a,:b}; say a\<b>;' True $ perl6 -e 'class A { our sub foo ($a) { "OHAI $a".say } }; A::foo\ (42)' OHAI 42 $ perl6 -e 'say IO::Path\ .^name;' IO::Path $ perl6 -e 'IO::Path\.^name.say' IO::Path $ perl6 -e 'class A { our @a = 1,2; }; say @A::a\ [1]' 2 $ perl6 -e 'class A { our @a = 1,2; }; say @A::a\[1]' 2 $ perl6 -e 'class A { our %a = :a,:b; }; say %A::a\{"b"}' True $ perl6 -e 'class A { our %a = :a,:b; }; say %A::a\ {"b"}' True $ perl6 -e 'class A { our %a = :a,:b; }; say %A::a\ <b>' True $ perl6 -e 'class A { our %a = :a,:b; }; say %A::a\<b>' True