summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-30 20:26:34 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-25 23:48:02 -0700
commit137da2b05b4b7628115049f343163bdaf2c30dbb (patch)
treef67f94858229947447c68a9676d49af49c593d4b /t
parentd2440203227a535b62a2078d898d0bd993ceac78 (diff)
downloadperl-137da2b05b4b7628115049f343163bdaf2c30dbb.tar.gz
[perl #79908] Stop sub inlining from breaking closures
When a closure closes over a variable, it references the variable itself, as opposed to taking a snapshot of its value. This was broken by the constant optimisation added for constant.pm’s sake: { my $x; sub () { $x }; # takes a snapshot of the current value of $x } constant.pm no longer uses that mechanism, except on older perls, so we can remove this hack, causing code like this this to start work- ing again: BEGIN{ my $x = 5; *foo = sub(){$x}; $x = 6 } print foo; # now prints 6, not 5
Diffstat (limited to 't')
-rw-r--r--t/op/sub.t21
1 files changed, 20 insertions, 1 deletions
diff --git a/t/op/sub.t b/t/op/sub.t
index 3546880157..56bbaaec66 100644
--- a/t/op/sub.t
+++ b/t/op/sub.t
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}
-plan( tests => 23 );
+plan( tests => 26 );
sub empty_sub {}
@@ -142,3 +142,22 @@ eval { ${\not_constantm}++ };
is $@, "", 'my sub (){42} returns a mutable value';
eval { ${\not_constantmr}++ };
is $@, "", 'my sub (){ return 42 } returns a mutable value';
+
+# [perl #79908]
+{
+ my $x = 5;
+ *_79908 = sub (){$x};
+ $x = 7;
+ is eval "_79908", 7, 'sub(){$x} does not break closures';
+ isnt eval '\_79908', \$x, 'sub(){$x} returns a copy';
+
+ # Test another thing that was broken by $x inlinement
+ my $y;
+ no warnings 'once';
+ local *time = sub():method{$y};
+ my $w;
+ local $SIG{__WARN__} = sub { $w .= shift };
+ eval "()=time";
+ is $w, undef,
+ '*keyword = sub():method{$y} does not cause ambiguity warnings';
+}