develooper Front page | perl.perl5.porters | Postings from February 2018

Re: [perl #132760] Blead Breaks CPAN: YANICK/List-Lazy-0.3.0.tar.gz

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
February 26, 2018 23:48
Subject:
Re: [perl #132760] Blead Breaks CPAN: YANICK/List-Lazy-0.3.0.tar.gz
Message ID:
20180226234800.GX3216@iabyn.com
On Thu, Feb 22, 2018 at 10:27:18AM +0000, Dave Mitchell wrote:
> I plan to do the following two things shortly (assuming they prove
> feasible):
> 
> 1) change the parser so that subs under 'use feature signatures' use
> a different grammar rule than subs not under it - possibly by making the
> toker return two different sub tokens, e.g. 'SUB' and a new 'SIGSUB'
> token say, depending on whether the feature is in scope.
> 
> This will then help reduce confusing errors, e.g. this code with a syntax
> error (attrs before prototype):
> 
>     no feature 'signatures';
>     sub f :lvalue ($$@) { $x = 1 }
> 
> currently gives:
> 
>     Illegal character following sigil in a subroutine signature at
>         ..., near "($"
> 
> It's parsing the ($$@) as a sub signature even though signatures aren't in
> scope, so the error message is confusing.
> 
> 2) For the signature sub grammar rule, allow it to spot attributes
> following a signature and croak with a meaningful error. Which is what the
> OP requested.

I've now done this and pushed as branch smoke-me/davem/sig_attr_croak.
If there's a rough consensus, I'll merge it soon.

The two important commits in that branch are:

commit 07431a29bfffc7fd1a18622437c1adf1658b6447
Author:     David Mitchell <davem@iabyn.com>
AuthorDate: Mon Feb 26 18:52:23 2018 +0000
Commit:     David Mitchell <davem@iabyn.com>
CommitDate: Mon Feb 26 22:36:25 2018 +0000

    detect sub attributes following a signature
    
    RT #132760
    
    A recent commit (v5.27.7-212-g894f226) moved subroutine attributes back
    before the subroutine's signature: e.g.
    
        sub foo :prototype($$) ($a, $b) { ... }  # 5.18 and 5.28 +
        sub foo ($a, $b) :prototype($$) { ... }  # 5.20 .. 5.26
    
    This change means that any code still using an attribute following the
    signature is going to trigger a syntax error. However, the error, followed
    by error recovery and further warnings and errors, is very unfriendly and
    gives no indication of the root cause. This commit introduces a new error,
    "Subroutine attributes must come before the signature".
    
    For example, List::Lazy, the subject of the ticket, failed to compile
    tests, with output like:
    
        Array found where operator expected at blib/lib/List/Lazy.pm line 43,
        near "$$@)" (Missing operator before @)?)
        "my" variable $step masks earlier declaration in same statement at
        blib/lib/List/Lazy.pm line 44.
        syntax error at blib/lib/List/Lazy.pm line 36, near ") :"
        Global symbol "$generator" requires explicit package name (did you
        forget to declare "my $generator"?) at blib/lib/List/Lazy.pm line 38.
        Global symbol "$state" requires explicit package name (did you forget
        to declare "my $state"?) at blib/lib/List/Lazy.pm line 39.
        Global symbol "$min" requires explicit package name (did you forget to
        declare "my $min"?) at blib/lib/List/Lazy.pm line 43.
        Global symbol "$max" requires explicit package name (did you forget to
        declare "my $max"?) at blib/lib/List/Lazy.pm line 43.
        Global symbol "$step" requires explicit package name (did you forget
        to declare "my $step"?) at blib/lib/List/Lazy.pm line 43.
        Invalid separator character '{' in attribute list at
        blib/lib/List/Lazy.pm line 44, near "$step : sub "
        Global symbol "$step" requires explicit package name (did you forget
        to declare "my $step"?) at blib/lib/List/Lazy.pm line 44.
    
    But following this commit, it now just outputs:
    
        Subroutine attributes must come before the signature at
        blib/lib/List/Lazy.pm line 36.
        Compilation failed in require at t/append.t line 5.
        BEGIN failed--compilation aborted at t/append.t line 5.
    
    It works by:
    
    1) adding a boolean flag (sig_seen) to the parser state to indicate that a
       signature has been parsed;
    2) at the end of parsing a signature, PL_expect is set to XATTRBLOCK
       rather than XBLOCK.
    
    Then if something looking like one or more attributes is encountered
    by the lexer immediately afterwards, it scans it as if it were an
    attribute, but then if sig_seen is true, it croaks.


commit a47e28076528d59784236975c73da1d513a8d0cd
Author:     David Mitchell <davem@iabyn.com>
AuthorDate: Thu Feb 22 14:44:51 2018 +0000
Commit:     David Mitchell <davem@iabyn.com>
CommitDate: Mon Feb 26 22:36:05 2018 +0000

    rationalise subroutine parsing rules
    
    Now that the parser rules have been split into separate rules for subs
    under 'use feature "signatures"' and not, refine the rules to reflect the
    different regimes. In particular:
    
    1) no longer include 'proto' in the signature variants: as it happens the
    toker would never return a proto THING under signatures anyway, but
    removing it from the grammar makes it clearer what's expected and not
    expected.
    
    2) Remove 'subsignature' from non-sig rules: what used to happen before
    was that outside of 'use feature "signatures"', it might still try to
    parse a signature, e.g.
    
        $ perl5279 -we 'sub f :lvalue ($$@) { $x = 1 }'
        Illegal character following sigil in a subroutine signature at -e line
        1, near "($"
        syntax error at -e line 1, near "$$@"
    
    Now it's just a plain syntax error.


-- 
"Foul and greedy Dwarf - you have eaten the last candle."
    -- "Hordes of the Things", BBC Radio.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About