diff options
author | James E Keenan <jkeenan@cpan.org> | 2019-05-25 21:40:00 -0400 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2019-10-02 14:59:31 +1000 |
commit | 30fc7a2809e5a175e2d9bb94d765b2039f270d91 (patch) | |
tree | 2323f07cd017b3484aa4ed1a8c06255b2cf90334 | |
parent | e55ec392015ba0c575cf495206c3121d1989561b (diff) | |
download | perl-30fc7a2809e5a175e2d9bb94d765b2039f270d91.tar.gz |
Eliminate modifiable variables in constants
Transform previously deprecated cases into exceptions.
Update diagnostic; change D to F
remove now irrelevant code (TonyC)
For: RT 134138
-rw-r--r-- | pad.c | 22 | ||||
-rw-r--r-- | pod/perldiag.pod | 7 | ||||
-rw-r--r-- | t/op/const-optree.t | 44 |
3 files changed, 25 insertions, 48 deletions
@@ -2127,7 +2127,6 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned, * from the parent */ if (const_sv && SvREFCNT(const_sv) == 2) { const bool was_method = cBOOL(CvMETHOD(cv)); - bool copied = FALSE; if (outside) { PADNAME * const pn = PadlistNAMESARRAY(CvPADLIST(outside)) @@ -2156,28 +2155,15 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned, ) == o && !OpSIBLING(o)) { - Perl_ck_warner_d(aTHX_ - packWARN(WARN_DEPRECATED), - "Constants from lexical " - "variables potentially " - "modified elsewhere are " - "deprecated. This will not " - "be allowed in Perl 5.32"); - /* We *copy* the lexical variable, and donate the - copy to newCONSTSUB. Yes, this is ugly, and - should be killed. We need to do this for the - time being, however, because turning on SvPADTMP - on a lexical will have observable effects - elsewhere. */ - const_sv = newSVsv(const_sv); - copied = TRUE; + Perl_croak(aTHX_ + "Constants from lexical variables potentially modified " + "elsewhere are no longer permitted"); } else goto constoff; } } - if (!copied) - SvREFCNT_inc_simple_void_NN(const_sv); + SvREFCNT_inc_simple_void_NN(const_sv); /* If the lexical is not used elsewhere, it is safe to turn on SvPADTMP, since it is only when it is used in lvalue con- text that the difference is observable. */ diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 2aaa5030ec..0144f99e49 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -1833,10 +1833,9 @@ The message indicates the type of reference that was expected. This usually indicates a syntax error in dereferencing the constant value. See L<perlsub/"Constant Functions"> and L<constant>. -=item Constants from lexical variables potentially modified elsewhere are -deprecated. This will not be allowed in Perl 5.32 +=item Constants from lexical variables potentially modified elsewhere are no longer permitted -(D deprecated) You wrote something like +(F) You wrote something like my $var; $sub = sub () { $var }; @@ -1853,7 +1852,7 @@ breaks the behavior of closures, in which the subroutine captures the variable itself, rather than its value, so future changes to the variable are reflected in the subroutine's return value. -This usage is deprecated, and will no longer be allowed in Perl 5.32, +This usage was deprecated, and as of Perl 5.32 is no longer allowed, making it possible to change the behavior in the future. If you intended for the subroutine to be eligible for inlining, then diff --git a/t/op/const-optree.t b/t/op/const-optree.t index 4d897d247e..3a8181beb8 100644 --- a/t/op/const-optree.t +++ b/t/op/const-optree.t @@ -8,7 +8,7 @@ BEGIN { require './test.pl'; set_up_inc('../lib'); } -plan 168; +plan 148; # @tests is an array of hash refs, each of which can have various keys: # @@ -25,6 +25,11 @@ plan 168; # deprecated - whether the sub returning a code ref will emit a depreca- # tion warning when called # method - whether the sub has the :method attribute +# exception - sub now throws an exception (previously threw +# deprecation warning) + +my $exception_134138 = 'Constants from lexical variables potentially modified ' + . 'elsewhere are no longer permitted'; # [perl #63540] Don’t treat sub { if(){.....}; "constant" } as a constant sub blonk { ++$blonk_was_called } @@ -47,11 +52,7 @@ push @tests, { push @tests, { nickname => 'sub with simple lexical modified elsewhere', generator => sub { my $x = 5; my $ret = sub(){$x}; $x = 7; $ret }, - retval => 5, # change to 7 when the deprecation cycle is over - same_retval => 0, - inlinable => 1, - deprecated => 1, - method => 0, + exception => $exception_134138, }; push @tests, { @@ -184,11 +185,7 @@ push @tests, { my $sub1 = sub () { $x++ }; $ret; }, - retval => 5, - same_retval => 0, - inlinable => 1, - deprecated => 1, - method => 0, + exception => $exception_134138, }; push @tests, { nickname => 'complex lexical op tree before an lvalue closure', @@ -307,11 +304,7 @@ push @tests, { eval '$outer++'; $ret; }, - retval => 43, - same_retval => 0, - inlinable => 1, - deprecated => 1, - method => 0, + exception => $exception_134138, }; push @tests, { nickname => 'sub () { $x } with s///ee in scope', @@ -322,11 +315,7 @@ push @tests, { $dummy =~ s//$dummy/ee; $ret; }, - retval => 43, - same_retval => 0, - inlinable => 1, - deprecated => 1, - method => 0, + exception => $exception_134138, }; push @tests, { nickname => 'sub () { $x } with eval not in scope', @@ -414,11 +403,7 @@ push @tests, { push @tests, { nickname => 'sub closing over state var++', generator => sub { state $x++; sub () { $x } }, - retval => 1, - same_retval => 0, - inlinable => 1, - deprecated => 1, - method => 0, + exception => $exception_134138, }; @@ -426,6 +411,12 @@ use feature 'refaliasing'; no warnings 'experimental::refaliasing'; for \%_ (@tests) { my $nickname = $_{nickname}; + if (exists $_{exception} and $_{exception}) { + local $@; + eval { my $sub = &{$_{generator}}; }; + like($@, qr/$_{exception}/, "$nickname: now throws exception (RT 134138)"); + next; + } my $w; local $SIG{__WARN__} = sub { $w = shift }; my $sub = &{$_{generator}}; @@ -492,3 +483,4 @@ pass("No assertion failure when turning on PADSTALE on lexical shared by" $z = &$sub; is $z, $y, 'inlinable sub ret vals are not swipable'; } + |