This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
sub foo($_) {...} - change error message
authorDavid Mitchell <davem@iabyn.com>
Mon, 23 Sep 2019 14:22:11 +0000 (15:22 +0100)
committerDavid Mitchell <davem@iabyn.com>
Mon, 23 Sep 2019 14:27:43 +0000 (15:27 +0100)
When using one of the globals like $_ or @_ in a subroutine signature,
the error message was misleading:

    Can't use global $_ in "my"

This commit changes it to:

    Can't use global $_ in subroutine signature

op.c
pod/perldiag.pod
t/op/signatures.t

diff --git a/op.c b/op.c
index 89d75dc..e875a90 100644 (file)
--- a/op.c
+++ b/op.c
@@ -700,16 +700,22 @@ Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags)
                 && isIDFIRST_utf8_safe((U8 *)name+1, name + len))
             || (name[1] == '_' && len > 2)))
     {
+        const char * const type =
+              PL_parser->in_my == KEY_sigvar ? "subroutine signature" :
+              PL_parser->in_my == KEY_state  ? "\"state\""     : "\"my\"";
+
        if (!(flags & SVf_UTF8 && UTF8_IS_START(name[1]))
         && isASCII(name[1])
         && (!isPRINT(name[1]) || strchr("\t\n\r\f", name[1]))) {
-           /* diag_listed_as: Can't use global %s in "%s" */
-           yyerror(Perl_form(aTHX_ "Can't use global %c^%c%.*s in \"%s\"",
-                             name[0], toCTRL(name[1]), (int)(len - 2), name + 2,
-                             PL_parser->in_my == KEY_state ? "state" : "my"));
+           /* diag_listed_as: Can't use global %s in %s */
+           yyerror(Perl_form(aTHX_ "Can't use global %c^%c%.*s in %s",
+                             name[0], toCTRL(name[1]),
+                              (int)(len - 2), name + 2,
+                             type));
        } else {
-           yyerror_pv(Perl_form(aTHX_ "Can't use global %.*s in \"%s\"", (int) len, name,
-                             PL_parser->in_my == KEY_state ? "state" : "my"), flags & SVf_UTF8);
+           yyerror_pv(Perl_form(aTHX_ "Can't use global %.*s in %s",
+                              (int) len, name,
+                             type), flags & SVf_UTF8);
        }
     }
 
index 2fa4b62..2aaa503 100644 (file)
@@ -1499,7 +1499,7 @@ it's loaded, etc.
 
 (P) The parser got confused when trying to parse a C<foreach> loop.
 
-=item Can't use global %s in "%s"
+=item Can't use global %s in %s
 
 (F) You tried to declare a magical variable as a lexical variable.  This
 is not allowed, because the magic can be tied to only one location
index a2dad42..80fde83 100644 (file)
@@ -1126,10 +1126,10 @@ syntax error at foo line 8, near "\$\$) "
 EOF
 
 eval "#line 8 foo\nsub t101 (\@_) { }";
-like $@, qr/\ACan't use global \@_ in "my" at foo line 8/;
+like $@, qr/\ACan't use global \@_ in subroutine signature at foo line 8/;
 
 eval "#line 8 foo\nsub t102 (\%_) { }";
-like $@, qr/\ACan't use global \%_ in "my" at foo line 8/;
+like $@, qr/\ACan't use global \%_ in subroutine signature at foo line 8/;
 
 my $t103 = sub ($a) { $a || "z" };
 is prototype($t103), undef;
@@ -1575,6 +1575,19 @@ while(<$kh>) {
     like $warn[3], qr/line 8,/, 'multiline1: $e';
 }
 
+# check errors for using global vars as params
+
+{
+    eval q{ sub ($_) {} };
+    like $@, qr/Can't use global \$_ in subroutine signature/, 'f($_)';
+    eval q{ sub (@_) {} };
+    like $@, qr/Can't use global \@_ in subroutine signature/, 'f(@_)';
+    eval q{ sub (%_) {} };
+    like $@, qr/Can't use global \%_ in subroutine signature/, 'f(%_)';
+    eval q{ sub ($1) {} };
+    like $@, qr/Illegal operator following parameter in a subroutine signature/,
+            'f($1)';
+}
 
 done_testing;