diff --git a/MANIFEST b/MANIFEST index a9abbf69fce4..71ebd5b41286 100644 --- a/MANIFEST +++ b/MANIFEST @@ -6105,6 +6105,7 @@ t/lib/Devel/switchd_empty.pm Module for t/run/switchd.t t/lib/Devel/switchd_goto.pm Module for t/run/switchd.t t/lib/Dies.pm For test case in op/require_errors.t t/lib/feature/api Test API for checking features enabled/disabled +t/lib/feature/apos_as_pack_sep Tests for enabling/disabling apostrophe_as_package_separator feature t/lib/feature/bareword_filehandles Tests for enabling/disabling bareword_filehandles feature t/lib/feature/bits Tests for feature bit handling t/lib/feature/bundle Tests for feature bundles diff --git a/cpan/Scalar-List-Utils/ListUtil.xs b/cpan/Scalar-List-Utils/ListUtil.xs index f67e9d4e1af2..855d8abdcaf2 100644 --- a/cpan/Scalar-List-Utils/ListUtil.xs +++ b/cpan/Scalar-List-Utils/ListUtil.xs @@ -1951,10 +1951,8 @@ PREINIT: STRLEN namelen; const char* nameptr = SvPV(name, namelen); int utf8flag = SvUTF8(name); -#if PERL_VERSION_LT(5, 41, 3) int quotes_seen = 0; bool need_subst = FALSE; -#endif PPCODE: if (!SvROK(sub) && SvGMAGICAL(sub)) mg_get(sub); @@ -1977,23 +1975,18 @@ PPCODE: if (s > nameptr && *s == ':' && s[-1] == ':') { end = s - 1; begin = ++s; -#if PERL_VERSION_LT(5, 41, 3) if (quotes_seen) need_subst = TRUE; -#endif } -#if PERL_VERSION_LT(5, 41, 3) else if (s > nameptr && *s != '\0' && s[-1] == '\'') { end = s - 1; begin = s; if (quotes_seen++) need_subst = TRUE; } -#endif } s--; if (end) { -#if PERL_VERSION_LT(5, 41, 3) SV* tmp; if (need_subst) { STRLEN length = end - nameptr + quotes_seen - (*end == '\'' ? 1 : 0); @@ -2013,7 +2006,6 @@ PPCODE: stash = gv_stashpvn(left, length, GV_ADD | utf8flag); } else -#endif stash = gv_stashpvn(nameptr, end - nameptr, GV_ADD | utf8flag); nameptr = begin; namelen -= begin - nameptr; diff --git a/cpan/Scalar-List-Utils/lib/List/Util.pm b/cpan/Scalar-List-Utils/lib/List/Util.pm index e50aefa63d50..f5ab5c8ff366 100644 --- a/cpan/Scalar-List-Utils/lib/List/Util.pm +++ b/cpan/Scalar-List-Utils/lib/List/Util.pm @@ -16,7 +16,7 @@ our @EXPORT_OK = qw( sample shuffle uniq uniqint uniqnum uniqstr zip zip_longest zip_shortest mesh mesh_longest mesh_shortest head tail pairs unpairs pairkeys pairvalues pairmap pairgrep pairfirst ); -our $VERSION = "1.68"; +our $VERSION = "1.68_01"; our $XS_VERSION = $VERSION; $VERSION =~ tr/_//d; diff --git a/cpan/Scalar-List-Utils/lib/List/Util/XS.pm b/cpan/Scalar-List-Utils/lib/List/Util/XS.pm index bac76f18eb17..801de5cf50de 100644 --- a/cpan/Scalar-List-Utils/lib/List/Util/XS.pm +++ b/cpan/Scalar-List-Utils/lib/List/Util/XS.pm @@ -3,7 +3,7 @@ use strict; use warnings; use List::Util; -our $VERSION = "1.68"; # FIXUP +our $VERSION = "1.68_01"; # FIXUP $VERSION =~ tr/_//d; # FIXUP 1; diff --git a/cpan/Scalar-List-Utils/lib/Scalar/Util.pm b/cpan/Scalar-List-Utils/lib/Scalar/Util.pm index 0ba9af2fddc9..8562a09026d1 100644 --- a/cpan/Scalar-List-Utils/lib/Scalar/Util.pm +++ b/cpan/Scalar-List-Utils/lib/Scalar/Util.pm @@ -17,7 +17,7 @@ our @EXPORT_OK = qw( dualvar isdual isvstring looks_like_number openhandle readonly set_prototype tainted ); -our $VERSION = "1.68"; +our $VERSION = "1.68_01"; $VERSION =~ tr/_//d; require List::Util; # List::Util loads the XS diff --git a/cpan/Scalar-List-Utils/lib/Sub/Util.pm b/cpan/Scalar-List-Utils/lib/Sub/Util.pm index e7a5aaff2de7..4a441163a677 100644 --- a/cpan/Scalar-List-Utils/lib/Sub/Util.pm +++ b/cpan/Scalar-List-Utils/lib/Sub/Util.pm @@ -15,7 +15,7 @@ our @EXPORT_OK = qw( subname set_subname ); -our $VERSION = "1.68"; +our $VERSION = "1.68_01"; $VERSION =~ tr/_//d; require List::Util; # as it has the XS diff --git a/cpan/Scalar-List-Utils/t/exotic_names.t b/cpan/Scalar-List-Utils/t/exotic_names.t index 15d1ff1c9517..395a817ef8ee 100644 --- a/cpan/Scalar-List-Utils/t/exotic_names.t +++ b/cpan/Scalar-List-Utils/t/exotic_names.t @@ -45,7 +45,7 @@ sub caller3_ok { ), ); - $expected =~ s/'/::/g if $] < 5.041_003; + $expected =~ s/'/::/g if $] < 5.037009 || $] >= 5.041_004; # this is apparently how things worked before 5.16 utf8::encode($expected) if $] < 5.016 and $ord > 255; @@ -72,7 +72,7 @@ my @ordinal = ( ($] >= 5.014 ? ( 0 ) : ()), 1 .. 38, # single quote ' separators are deprecated in 5.37.9 - ($] < 5.037009 ? ( 39 ) : ()), + ($] < 5.037009 || $] >= 5.041_004 ? ( 39 ) : ()), 40 .. 255, # Unicode in 5.6 is not sane (crashes etc) ($] >= 5.008 ? ( @@ -85,7 +85,7 @@ my @ordinal = ( my $legal_ident_char = join('', "A-Z_a-z0-9", - ($] < 5.037009 ? q['] : ()), + ($] < 5.037009 || $] >= 5.041_004 ? q['] : ()), ($] > 5.008 ? ( map chr, 0x100, 0x498 ) : ()), diff --git a/cpan/parent/lib/parent.pm b/cpan/parent/lib/parent.pm index 89c9ff84cf74..09d89cffac11 100644 --- a/cpan/parent/lib/parent.pm +++ b/cpan/parent/lib/parent.pm @@ -1,7 +1,7 @@ package parent; use strict; -our $VERSION = '0.242'; +our $VERSION = '0.242_001'; sub import { my $class = shift; diff --git a/cpan/parent/t/compile-time-file.t b/cpan/parent/t/compile-time-file.t index 0fcf8d8a2a65..0fc2ad9d4d75 100644 --- a/cpan/parent/t/compile-time-file.t +++ b/cpan/parent/t/compile-time-file.t @@ -24,7 +24,7 @@ use lib 't/lib'; { package Child3; - use if $] < 5.041_003, parent => "Dummy'Outside"; + use if $] != 5.041_003, parent => "Dummy'Outside"; } my $obj = {}; @@ -41,11 +41,10 @@ is $obj->exclaim, "I CAN FROM Dummy::InlineChild", 'Inheritance is set up correc SKIP: { - skip "No ' in names from 5.041_003", 3 if $] >= 5.041_003; -$obj = {}; -bless $obj, 'Child3'; -isa_ok $obj, 'Dummy::Outside'; -can_ok $obj, 'exclaim'; -is $obj->exclaim, "I CAN FROM Dummy::Outside", "Inheritance is set up correctly for classes inherited from via '"; - + skip "No ' in names in 5.041_003", 3 if $] == 5.041_003; + $obj = {}; + bless $obj, 'Child3'; + isa_ok $obj, 'Dummy::Outside'; + can_ok $obj, 'exclaim'; + is $obj->exclaim, "I CAN FROM Dummy::Outside", "Inheritance is set up correctly for classes inherited from via '"; } diff --git a/feature.h b/feature.h index a7c0b0568c94..c5e85c5d2a8b 100644 --- a/feature.h +++ b/feature.h @@ -12,27 +12,28 @@ #define HINT_FEATURE_SHIFT 26 -#define FEATURE_BAREWORD_FILEHANDLES_BIT 0x0001 -#define FEATURE_BITWISE_BIT 0x0002 -#define FEATURE_CLASS_BIT 0x0004 -#define FEATURE___SUB___BIT 0x0008 -#define FEATURE_MYREF_BIT 0x0010 -#define FEATURE_DEFER_BIT 0x0020 -#define FEATURE_EVALBYTES_BIT 0x0040 -#define FEATURE_MORE_DELIMS_BIT 0x0080 -#define FEATURE_FC_BIT 0x0100 -#define FEATURE_INDIRECT_BIT 0x0200 -#define FEATURE_ISA_BIT 0x0400 -#define FEATURE_MODULE_TRUE_BIT 0x0800 -#define FEATURE_MULTIDIMENSIONAL_BIT 0x1000 -#define FEATURE_POSTDEREF_QQ_BIT 0x2000 -#define FEATURE_REFALIASING_BIT 0x4000 -#define FEATURE_SAY_BIT 0x8000 -#define FEATURE_SIGNATURES_BIT 0x10000 -#define FEATURE_STATE_BIT 0x20000 -#define FEATURE_TRY_BIT 0x40000 -#define FEATURE_UNIEVAL_BIT 0x80000 -#define FEATURE_UNICODE_BIT 0x100000 +#define FEATURE_APOS_AS_NAME_SEP_BIT 0x0001 +#define FEATURE_BAREWORD_FILEHANDLES_BIT 0x0002 +#define FEATURE_BITWISE_BIT 0x0004 +#define FEATURE_CLASS_BIT 0x0008 +#define FEATURE___SUB___BIT 0x0010 +#define FEATURE_MYREF_BIT 0x0020 +#define FEATURE_DEFER_BIT 0x0040 +#define FEATURE_EVALBYTES_BIT 0x0080 +#define FEATURE_MORE_DELIMS_BIT 0x0100 +#define FEATURE_FC_BIT 0x0200 +#define FEATURE_INDIRECT_BIT 0x0400 +#define FEATURE_ISA_BIT 0x0800 +#define FEATURE_MODULE_TRUE_BIT 0x1000 +#define FEATURE_MULTIDIMENSIONAL_BIT 0x2000 +#define FEATURE_POSTDEREF_QQ_BIT 0x4000 +#define FEATURE_REFALIASING_BIT 0x8000 +#define FEATURE_SAY_BIT 0x10000 +#define FEATURE_SIGNATURES_BIT 0x20000 +#define FEATURE_STATE_BIT 0x40000 +#define FEATURE_TRY_BIT 0x80000 +#define FEATURE_UNIEVAL_BIT 0x100000 +#define FEATURE_UNICODE_BIT 0x200000 #define FEATURE_BUNDLE_DEFAULT 0 #define FEATURE_BUNDLE_510 1 @@ -43,6 +44,7 @@ #define FEATURE_BUNDLE_535 6 #define FEATURE_BUNDLE_537 7 #define FEATURE_BUNDLE_539 8 +#define FEATURE_BUNDLE_541 9 #define FEATURE_BUNDLE_CUSTOM (HINT_FEATURE_MASK >> HINT_FEATURE_SHIFT) /* this is preserved for testing and asserts */ @@ -65,7 +67,7 @@ #define FEATURE_FC_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_FC_BIT)) \ ) @@ -73,7 +75,7 @@ #define FEATURE_ISA_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_535 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_ISA_BIT)) \ ) @@ -81,14 +83,15 @@ #define FEATURE_SAY_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_SAY_BIT)) \ ) #define FEATURE_TRY_IS_ENABLED \ ( \ - CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_539 \ + (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_539 && \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_TRY_BIT)) \ ) @@ -108,7 +111,7 @@ #define FEATURE_STATE_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_STATE_BIT)) \ ) @@ -116,7 +119,7 @@ #define FEATURE_BITWISE_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_527 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_BITWISE_BIT)) \ ) @@ -131,7 +134,7 @@ #define FEATURE_EVALBYTES_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_EVALBYTES_BIT)) \ ) @@ -139,7 +142,7 @@ #define FEATURE_SIGNATURES_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_535 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_SIGNATURES_BIT)) \ ) @@ -147,7 +150,7 @@ #define FEATURE___SUB___IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE___SUB___BIT)) \ ) @@ -155,7 +158,7 @@ #define FEATURE_MODULE_TRUE_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_537 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_MODULE_TRUE_BIT)) \ ) @@ -169,7 +172,7 @@ #define FEATURE_POSTDEREF_QQ_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_523 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_POSTDEREF_QQ_BIT)) \ ) @@ -177,7 +180,7 @@ #define FEATURE_UNIEVAL_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_UNIEVAL_BIT)) \ ) @@ -191,7 +194,7 @@ #define FEATURE_UNICODE_IS_ENABLED \ ( \ (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_511 && \ - CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539) \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_541) \ || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ FEATURE_IS_ENABLED_MASK(FEATURE_UNICODE_BIT)) \ ) @@ -216,6 +219,13 @@ FEATURE_IS_ENABLED_MASK(FEATURE_MORE_DELIMS_BIT) \ ) +#define FEATURE_APOS_AS_NAME_SEP_IS_ENABLED \ + ( \ + CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_539 \ + || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \ + FEATURE_IS_ENABLED_MASK(FEATURE_APOS_AS_NAME_SEP_BIT)) \ + ) + #define SAVEFEATUREBITS() SAVEI32(PL_compiling.cop_features) @@ -232,6 +242,9 @@ S_enable_feature_bundle(pTHX_ SV *ver) SV *comp_ver = sv_newmortal(); PL_hints = (PL_hints &~ HINT_FEATURE_MASK) | ( + (sv_setnv(comp_ver, 5.041), + vcmp(ver, upg_version(comp_ver, FALSE)) >= 0) + ? FEATURE_BUNDLE_541 : (sv_setnv(comp_ver, 5.039), vcmp(ver, upg_version(comp_ver, FALSE)) >= 0) ? FEATURE_BUNDLE_539 : @@ -287,6 +300,14 @@ S_magic_sethint_feature(pTHX_ SV *keysv, const char *keypv, STRLEN keylen, } return; + case 'a': + if (keylen == sizeof("feature_apos_as_name_sep")-1 + && memcmp(subf+1, "pos_as_name_sep", keylen - sizeof("feature_")) == 0) { + mask = FEATURE_APOS_AS_NAME_SEP_BIT; + break; + } + return; + case 'b': if (keylen == sizeof("feature_bareword_filehandles")-1 && memcmp(subf+1, "areword_filehandles", keylen - sizeof("feature_")) == 0) { @@ -445,6 +466,12 @@ struct perl_feature_bit { static const struct perl_feature_bit PL_feature_bits[] = { + { + /* feature apostrophe_as_package_separator */ + "feature_apos_as_name_sep", + STRLENs("feature_apos_as_name_sep"), + FEATURE_APOS_AS_NAME_SEP_BIT + }, { /* feature bareword_filehandles */ "feature_bareword_filehandles", diff --git a/gv.c b/gv.c index e0a3ef88ba95..bfd5f30fefae 100644 --- a/gv.c +++ b/gv.c @@ -1179,7 +1179,7 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le * method name. * * leaves last_separator pointing to the beginning of the - * last package separator (::) or 0 + * last package separator (either ' or ::) or 0 * if none was found. * * leaves name pointing at the beginning of the @@ -1188,7 +1188,11 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le const char *name_cursor = name; const char * const name_em1 = name_end - 1; /* name_end minus 1 */ for (name_cursor = name; name_cursor < name_end ; name_cursor++) { - if (name_cursor < name_em1 && *name_cursor == ':' && name_cursor[1] == ':') { + if (*name_cursor == '\'') { + last_separator = name_cursor; + name = name_cursor + 1; + } + else if (name_cursor < name_em1 && *name_cursor == ':' && name_cursor[1] == ':') { last_separator = name_cursor++; name = name_cursor + 1; } @@ -1798,6 +1802,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, const char *name_cursor; const char *const name_end = nambeg + full_len; const char *const name_em1 = name_end - 1; + char smallbuf[64]; /* small buffer to avoid a malloc when possible */ PERL_ARGS_ASSERT_PARSE_GV_STASH_NAME; @@ -1811,7 +1816,8 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, for (name_cursor = *name; name_cursor < name_end; name_cursor++) { if (name_cursor < name_em1 && - (*name_cursor == ':' && name_cursor[1] == ':')) + ((*name_cursor == ':' && name_cursor[1] == ':') + || *name_cursor == '\'')) { if (!*stash) *stash = PL_defstash; @@ -1826,6 +1832,22 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, key = *name; *len += 2; } + else { /* using ' for package separator */ + /* use our pre-allocated buffer when possible to save a malloc */ + char *tmpbuf; + if ( *len+2 <= sizeof smallbuf) + tmpbuf = smallbuf; + else { + /* only malloc once if needed */ + if (tmpfullbuf == NULL) /* only malloc&free once, a little more than needed */ + Newx(tmpfullbuf, full_len+2, char); + tmpbuf = tmpfullbuf; + } + Copy(*name, tmpbuf, *len, char); + tmpbuf[(*len)++] = ':'; + tmpbuf[(*len)++] = ':'; + key = tmpbuf; + } gvp = (GV**)hv_fetch(*stash, key, is_utf8 ? -((I32)*len) : (I32)*len, add); *gv = gvp ? *gvp : NULL; if (!*gv || *gv == (const GV *)&PL_sv_undef) { diff --git a/lib/feature.pm b/lib/feature.pm index cf0531845d13..8d1c930ca542 100644 --- a/lib/feature.pm +++ b/lib/feature.pm @@ -4,43 +4,45 @@ # Any changes made here will be lost! package feature; -our $VERSION = '1.91'; +our $VERSION = '1.92'; our %feature = ( - fc => 'feature_fc', - isa => 'feature_isa', - say => 'feature_say', - try => 'feature_try', - class => 'feature_class', - defer => 'feature_defer', - state => 'feature_state', - bitwise => 'feature_bitwise', - indirect => 'feature_indirect', - evalbytes => 'feature_evalbytes', - signatures => 'feature_signatures', - current_sub => 'feature___SUB__', - module_true => 'feature_module_true', - refaliasing => 'feature_refaliasing', - postderef_qq => 'feature_postderef_qq', - unicode_eval => 'feature_unieval', - declared_refs => 'feature_myref', - unicode_strings => 'feature_unicode', - multidimensional => 'feature_multidimensional', - bareword_filehandles => 'feature_bareword_filehandles', - extra_paired_delimiters => 'feature_more_delims', + fc => 'feature_fc', + isa => 'feature_isa', + say => 'feature_say', + try => 'feature_try', + class => 'feature_class', + defer => 'feature_defer', + state => 'feature_state', + bitwise => 'feature_bitwise', + indirect => 'feature_indirect', + evalbytes => 'feature_evalbytes', + signatures => 'feature_signatures', + current_sub => 'feature___SUB__', + module_true => 'feature_module_true', + refaliasing => 'feature_refaliasing', + postderef_qq => 'feature_postderef_qq', + unicode_eval => 'feature_unieval', + declared_refs => 'feature_myref', + unicode_strings => 'feature_unicode', + multidimensional => 'feature_multidimensional', + bareword_filehandles => 'feature_bareword_filehandles', + extra_paired_delimiters => 'feature_more_delims', + apostrophe_as_package_separator => 'feature_apos_as_name_sep', ); our %feature_bundle = ( - "5.10" => [qw(bareword_filehandles indirect multidimensional say state)], - "5.11" => [qw(bareword_filehandles indirect multidimensional say state unicode_strings)], - "5.15" => [qw(bareword_filehandles current_sub evalbytes fc indirect multidimensional say state unicode_eval unicode_strings)], - "5.23" => [qw(bareword_filehandles current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings)], - "5.27" => [qw(bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings)], - "5.35" => [qw(bareword_filehandles bitwise current_sub evalbytes fc isa postderef_qq say signatures state unicode_eval unicode_strings)], - "5.37" => [qw(bitwise current_sub evalbytes fc isa module_true postderef_qq say signatures state unicode_eval unicode_strings)], - "5.39" => [qw(bitwise current_sub evalbytes fc isa module_true postderef_qq say signatures state try unicode_eval unicode_strings)], - "all" => [qw(bareword_filehandles bitwise class current_sub declared_refs defer evalbytes extra_paired_delimiters fc indirect isa module_true multidimensional postderef_qq refaliasing say signatures state try unicode_eval unicode_strings)], - "default" => [qw(bareword_filehandles indirect multidimensional)], + "5.10" => [qw(apostrophe_as_package_separator bareword_filehandles indirect multidimensional say state)], + "5.11" => [qw(apostrophe_as_package_separator bareword_filehandles indirect multidimensional say state unicode_strings)], + "5.15" => [qw(apostrophe_as_package_separator bareword_filehandles current_sub evalbytes fc indirect multidimensional say state unicode_eval unicode_strings)], + "5.23" => [qw(apostrophe_as_package_separator bareword_filehandles current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings)], + "5.27" => [qw(apostrophe_as_package_separator bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings)], + "5.35" => [qw(apostrophe_as_package_separator bareword_filehandles bitwise current_sub evalbytes fc isa postderef_qq say signatures state unicode_eval unicode_strings)], + "5.37" => [qw(apostrophe_as_package_separator bitwise current_sub evalbytes fc isa module_true postderef_qq say signatures state unicode_eval unicode_strings)], + "5.39" => [qw(apostrophe_as_package_separator bitwise current_sub evalbytes fc isa module_true postderef_qq say signatures state try unicode_eval unicode_strings)], + "5.41" => [qw(bitwise current_sub evalbytes fc isa module_true postderef_qq say signatures state try unicode_eval unicode_strings)], + "all" => [qw(apostrophe_as_package_separator bareword_filehandles bitwise class current_sub declared_refs defer evalbytes extra_paired_delimiters fc indirect isa module_true multidimensional postderef_qq refaliasing say signatures state try unicode_eval unicode_strings)], + "default" => [qw(apostrophe_as_package_separator bareword_filehandles indirect multidimensional)], ); $feature_bundle{"5.12"} = $feature_bundle{"5.11"}; @@ -66,8 +68,7 @@ $feature_bundle{"5.34"} = $feature_bundle{"5.27"}; $feature_bundle{"5.36"} = $feature_bundle{"5.35"}; $feature_bundle{"5.38"} = $feature_bundle{"5.37"}; $feature_bundle{"5.40"} = $feature_bundle{"5.39"}; -$feature_bundle{"5.41"} = $feature_bundle{"5.39"}; -$feature_bundle{"5.42"} = $feature_bundle{"5.39"}; +$feature_bundle{"5.42"} = $feature_bundle{"5.41"}; $feature_bundle{"5.9.5"} = $feature_bundle{"5.10"}; my %noops = ( postderef => 1, @@ -80,7 +81,7 @@ my %removed = ( our $hint_shift = 26; our $hint_mask = 0x3c000000; -our @hint_bundles = qw( default 5.10 5.11 5.15 5.23 5.27 5.35 5.37 5.39 ); +our @hint_bundles = qw( default 5.10 5.11 5.15 5.23 5.27 5.35 5.37 5.39 5.41 ); # This gets set (for now) in $^H as well as in %^H, # for runtime speed of the uc/lc/ucfirst/lcfirst functions. @@ -506,6 +507,18 @@ warn when you use the feature, unless you have explicitly disabled the warning: This feature enables the C block syntax and other associated keywords which implement the "new" object system, previously codenamed "Corinna". +=head2 The 'apostrophe_as_package_separator' feature + +This feature enables use C<'> (apostrophe) as an alternative to using +C<::> as a separate in package and other global names. + +This is enabled by default, but disabled from the 5.41 feature bundle +onwards. In previous versions it was enabled all the time. + +This only disables C<'> in symbols in your source code, the internal +conversion from C<'> to C<::>, including for symbolic references, is +always enabled. + =head1 FEATURE BUNDLES It's possible to load multiple features together, using @@ -520,71 +533,88 @@ The following feature bundles are available: --------- ----------------- :default indirect multidimensional bareword_filehandles + apostrophe_as_package_separator - :5.10 bareword_filehandles indirect + :5.10 apostrophe_as_package_separator + bareword_filehandles indirect multidimensional say state - :5.12 bareword_filehandles indirect + :5.12 apostrophe_as_package_separator + bareword_filehandles indirect multidimensional say state unicode_strings - :5.14 bareword_filehandles indirect + :5.14 apostrophe_as_package_separator + bareword_filehandles indirect multidimensional say state unicode_strings - :5.16 bareword_filehandles current_sub evalbytes + :5.16 apostrophe_as_package_separator + bareword_filehandles current_sub evalbytes fc indirect multidimensional say state unicode_eval unicode_strings - :5.18 bareword_filehandles current_sub evalbytes + :5.18 apostrophe_as_package_separator + bareword_filehandles current_sub evalbytes fc indirect multidimensional say state unicode_eval unicode_strings - :5.20 bareword_filehandles current_sub evalbytes + :5.20 apostrophe_as_package_separator + bareword_filehandles current_sub evalbytes fc indirect multidimensional say state unicode_eval unicode_strings - :5.22 bareword_filehandles current_sub evalbytes + :5.22 apostrophe_as_package_separator + bareword_filehandles current_sub evalbytes fc indirect multidimensional say state unicode_eval unicode_strings - :5.24 bareword_filehandles current_sub evalbytes + :5.24 apostrophe_as_package_separator + bareword_filehandles current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings - :5.26 bareword_filehandles current_sub evalbytes + :5.26 apostrophe_as_package_separator + bareword_filehandles current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings - :5.28 bareword_filehandles bitwise current_sub + :5.28 apostrophe_as_package_separator + bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings - :5.30 bareword_filehandles bitwise current_sub + :5.30 apostrophe_as_package_separator + bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings - :5.32 bareword_filehandles bitwise current_sub + :5.32 apostrophe_as_package_separator + bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings - :5.34 bareword_filehandles bitwise current_sub + :5.34 apostrophe_as_package_separator + bareword_filehandles bitwise current_sub evalbytes fc indirect multidimensional postderef_qq say state unicode_eval unicode_strings - :5.36 bareword_filehandles bitwise current_sub + :5.36 apostrophe_as_package_separator + bareword_filehandles bitwise current_sub evalbytes fc isa postderef_qq say signatures state unicode_eval unicode_strings - :5.38 bitwise current_sub evalbytes fc isa - module_true postderef_qq say signatures - state unicode_eval unicode_strings + :5.38 apostrophe_as_package_separator bitwise + current_sub evalbytes fc isa module_true + postderef_qq say signatures state + unicode_eval unicode_strings - :5.40 bitwise current_sub evalbytes fc isa - module_true postderef_qq say signatures - state try unicode_eval unicode_strings + :5.40 apostrophe_as_package_separator bitwise + current_sub evalbytes fc isa module_true + postderef_qq say signatures state try + unicode_eval unicode_strings :5.42 bitwise current_sub evalbytes fc isa module_true postderef_qq say signatures diff --git a/lib/warnings.pm b/lib/warnings.pm index 11c09eaa0a28..7edc55640b51 100644 --- a/lib/warnings.pm +++ b/lib/warnings.pm @@ -5,7 +5,7 @@ package warnings; -our $VERSION = "1.70"; +our $VERSION = "1.71"; # Verify that we're called correctly so that warnings will work. # Can't use Carp, since Carp uses us! @@ -124,17 +124,14 @@ our %Offsets = ( # Warnings Categories added in Perl 5.037 'experimental::class' => 150, - # Warnings Categories added in Perl 5.037009 - 'deprecated::apostrophe_as_package_separator'=> 152, - # Warnings Categories added in Perl 5.03701 - 'deprecated::smartmatch' => 154, + 'deprecated::smartmatch' => 152, # Warnings Categories added in Perl 5.039002 - 'deprecated::missing_import_called_with_args'=> 156, + 'deprecated::missing_import_called_with_args'=> 154, # Warnings Categories added in Perl 5.039008 - 'deprecated::subsequent_use_version'=> 158, + 'deprecated::subsequent_use_version'=> 156, ); our %Bits = ( @@ -144,14 +141,13 @@ our %Bits = ( 'closed' => "\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6] 'closure' => "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1] 'debugging' => "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [22] - 'deprecated' => "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x10\x00\x00\x14\x55", # [2,48,49,62,73,74,76..79] - 'deprecated::apostrophe_as_package_separator'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [76] + 'deprecated' => "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x10\x00\x00\x14\x15", # [2,48,49,62,73,74,76..78] 'deprecated::delimiter_will_be_paired'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [74] 'deprecated::dot_in_inc' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [62] 'deprecated::goto_construct' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", # [48] - 'deprecated::missing_import_called_with_args'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [78] - 'deprecated::smartmatch' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [77] - 'deprecated::subsequent_use_version'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40", # [79] + 'deprecated::missing_import_called_with_args'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [77] + 'deprecated::smartmatch' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [76] + 'deprecated::subsequent_use_version'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [78] 'deprecated::unicode_property_name' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00", # [49] 'deprecated::version_downgrade' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [73] 'digit' => "\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [31] @@ -227,14 +223,13 @@ our %DeadBits = ( 'closed' => "\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6] 'closure' => "\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1] 'debugging' => "\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [22] - 'deprecated' => "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x20\x00\x00\x28\xaa", # [2,48,49,62,73,74,76..79] - 'deprecated::apostrophe_as_package_separator'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [76] + 'deprecated' => "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x20\x00\x00\x28\x2a", # [2,48,49,62,73,74,76..78] 'deprecated::delimiter_will_be_paired'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [74] 'deprecated::dot_in_inc' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [62] 'deprecated::goto_construct' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", # [48] - 'deprecated::missing_import_called_with_args'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [78] - 'deprecated::smartmatch' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [77] - 'deprecated::subsequent_use_version'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80", # [79] + 'deprecated::missing_import_called_with_args'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [77] + 'deprecated::smartmatch' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [76] + 'deprecated::subsequent_use_version'=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [78] 'deprecated::unicode_property_name' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00", # [49] 'deprecated::version_downgrade' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [73] 'digit' => "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [31] @@ -318,8 +313,8 @@ our %NoOp = ( # These are used by various things, including our own tests our $NONE = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -our $DEFAULT = "\x10\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x05\x00\x15\x14\x55\x55\x54\x55"; # [2,4,22,23,25,48,49,56..58,61,62,64..71,73..79] -our $LAST_BIT = 160 ; +our $DEFAULT = "\x10\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x05\x00\x15\x14\x55\x55\x54\x15"; # [2,4,22,23,25,48,49,56..58,61,62,64..71,73..78] +our $LAST_BIT = 158 ; our $BYTES = 20 ; sub Croaker @@ -922,8 +917,6 @@ The current hierarchy is: | +- deprecated ----+ | | - | +- deprecated::apostrophe_as_package_separator - | | | +- deprecated::delimiter_will_be_paired | | | +- deprecated::dot_in_inc diff --git a/mg.c b/mg.c index c37707be462d..d972781ff1fe 100644 --- a/mg.c +++ b/mg.c @@ -1853,7 +1853,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) * access to a known hint bit in a known OP, we can't * tell whether HINT_STRICT_REFS is in force or not. */ - if (!memchr(s, ':', len)) + if (!memchr(s, ':', len) && !memchr(s, '\'', len)) Perl_sv_insert_flags(aTHX_ sv, 0, 0, STR_WITH_LEN("main::"), SV_GMAGIC); if (i) diff --git a/op.c b/op.c index 4ba61a641d2e..4bc9a036644e 100644 --- a/op.c +++ b/op.c @@ -10717,7 +10717,7 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, ec ? GV_NOADD_NOINIT : (IN_PERL_RUNTIME && PL_curstash != CopSTASH(PL_curcop)) || PL_curstash != PL_defstash - || memchr(name, ':', namlen) + || memchr(name, ':', namlen) || memchr(name, '\'', namlen) ? gv_fetch_flags : GV_ADDMULTI | GV_NOINIT | GV_NOTQUAL; gv = gv_fetchsv(cSVOPo->op_sv, flags, SVt_PVCV); @@ -13380,6 +13380,7 @@ Perl_ck_method(pTHX_ OP *o) { SV *sv, *methsv, *rclass; const char* method; + char* compatptr; int utf8; STRLEN len, nsplit = 0, i; OP* new_op; @@ -13390,6 +13391,14 @@ Perl_ck_method(pTHX_ OP *o) sv = kSVOP->op_sv; + /* replace ' with :: */ + while ((compatptr = (char *) memchr(SvPVX(sv), '\'', + SvEND(sv) - SvPVX(sv) ))) + { + *compatptr = ':'; + sv_insert(sv, compatptr - SvPVX_const(sv), 0, ":", 1); + } + method = SvPVX_const(sv); len = SvCUR(sv); utf8 = SvUTF8(sv) ? -1 : 1; diff --git a/pod/perldeprecation.pod b/pod/perldeprecation.pod index 552624b536a0..b06797d82b58 100644 --- a/pod/perldeprecation.pod +++ b/pod/perldeprecation.pod @@ -97,16 +97,6 @@ your restraint. Category: "deprecated::goto_construct" -=head3 Use of C<'> as a global name separator - -Perl allows use of C<'> instead of C<::> to replace the parts of a -package or global variable name, for example C and C are -equivalent. - -C<'> will no longer be recognized as a name separator in Perl 5.42. - -Category: "deprecated::apostrophe_as_package_separator" - =head2 Perl 5.40 =head3 Downgrading a C to below v5.11 diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 1af0dcc364b1..ab08994aa0a4 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -487,7 +487,7 @@ results. of Perl. Check the #! line, or manually feed your script into Perl yourself. -=item Bad name after %s:: +=item Bad name after %s (F) You started to name a symbol by using a package prefix, and then didn't finish the symbol. In particular, you can't interpolate outside diff --git a/pod/perlmod.pod b/pod/perlmod.pod index 63516e55e2bb..e6f396f18f2a 100644 --- a/pod/perlmod.pod +++ b/pod/perlmod.pod @@ -69,6 +69,25 @@ colon: C<$Package::Variable>. If the package name is null, the C
package is assumed. That is, C<$::sail> is equivalent to C<$main::sail>. +The old package delimiter was a single quote, but double colon is now the +preferred delimiter, in part because it's more readable to humans, and +in part because it's more readable to B macros. It also makes C++ +programmers feel like they know what's going on--as opposed to using the +single quote as separator, which was there to make Ada programmers feel +like they knew what was going on. Because the old-fashioned syntax is still +supported for backwards compatibility, if you try to use a string like +C<"This is $owner's house">, you'll be accessing C<$owner::s>; that is, +the $s variable in package C, which is probably not what you meant. +Use braces to disambiguate, as in C<"This is ${owner}'s house">. +X<::> X<'> + + +Use of C<'> as a package delimiter can be disabled with: + + no feature 'apostrophe_as_package_separator'; + +and is also disabled by C or later. + Packages may themselves contain package separators, as in C<$OUTER::INNER::var>. This implies nothing about the order of name lookups, however. There are no relative packages: all symbols @@ -79,9 +98,6 @@ C<$OUTER::INNER::var>. C refers to a totally separate global package. The custom of treating package names as a hierarchy is very strong, but the language in no way enforces it. -Previously you could use C<'> as a package separator, this was removed -in Perl 5.42. - Only identifiers starting with letters (or underscore) are stored in a package's symbol table. All other symbols are kept in package C
, including all punctuation variables, like $_. In addition, diff --git a/regen/feature.pl b/regen/feature.pl index 40f74f34d1f9..9ff19fbfca1a 100755 --- a/regen/feature.pl +++ b/regen/feature.pl @@ -45,6 +45,7 @@ BEGIN extra_paired_delimiters => 'more_delims', module_true => 'module_true', class => 'class', + apostrophe_as_package_separator => 'apos_as_name_sep', ); # NOTE: If a feature is ever enabled in a non-contiguous range of Perl @@ -54,7 +55,7 @@ BEGIN # 5.odd implies the next 5.even, but an explicit 5.even can override it. # features bundles -use constant V5_9_5 => sort qw{say state indirect multidimensional bareword_filehandles}; +use constant V5_9_5 => sort qw{say state indirect multidimensional bareword_filehandles apostrophe_as_package_separator}; use constant V5_11 => sort ( +V5_9_5, qw{unicode_strings} ); use constant V5_15 => sort ( +V5_11, qw{unicode_eval evalbytes current_sub fc} ); use constant V5_23 => sort ( +V5_15, qw{postderef_qq} ); @@ -66,14 +67,17 @@ BEGIN use constant V5_37 => sort grep {; $_ ne 'bareword_filehandles' } +V5_35, qw{module_true}; use constant V5_39 => sort ( +V5_37, qw{try} ); -use constant V5_41 => sort ( +V5_39 ); +use constant V5_41 => sort + grep {; $_ ne 'apostrophe_as_package_separator' } + ( +V5_39 ); # # when updating features please also update the Pod entry for L # my %feature_bundle = ( all => [ sort keys %feature ], - default => [ qw{indirect multidimensional bareword_filehandles} ], + default => [ qw{indirect multidimensional bareword_filehandles + apostrophe_as_package_separator} ], # using 5.9.5 features bundle "5.9.5" => [ +V5_9_5 ], "5.10" => [ +V5_9_5 ], @@ -542,7 +546,7 @@ sub longest { __END__ package feature; -our $VERSION = '1.91'; +our $VERSION = '1.92'; FEATURES @@ -965,6 +969,18 @@ =head2 The 'class' feature This feature enables the C block syntax and other associated keywords which implement the "new" object system, previously codenamed "Corinna". +=head2 The 'apostrophe_as_package_separator' feature + +This feature enables use C<'> (apostrophe) as an alternative to using +C<::> as a separate in package and other global names. + +This is enabled by default, but disabled from the 5.41 feature bundle +onwards. In previous versions it was enabled all the time. + +This only disables C<'> in symbols in your source code, the internal +conversion from C<'> to C<::>, including for symbolic references, is +always enabled. + =head1 FEATURE BUNDLES It's possible to load multiple features together, using diff --git a/regen/warnings.pl b/regen/warnings.pl index a7084f5827a5..b39c4ad177c0 100644 --- a/regen/warnings.pl +++ b/regen/warnings.pl @@ -16,7 +16,7 @@ # # This script is normally invoked from regen.pl. -$VERSION = '1.70'; +$VERSION = '1.71'; BEGIN { require './regen/regen_lib.pl'; @@ -80,8 +80,6 @@ BEGIN 'deprecated::dot_in_inc' => [ 5.025011, DEFAULT_ON], 'deprecated::version_downgrade' => [ 5.035009, DEFAULT_ON], 'deprecated::delimiter_will_be_paired' => [ 5.035010, DEFAULT_ON], - 'deprecated::apostrophe_as_package_separator' - => [ 5.037009, DEFAULT_ON], 'deprecated::smartmatch' => [ 5.037010, DEFAULT_ON], 'deprecated::missing_import_called_with_args' => [ 5.039002, DEFAULT_ON], diff --git a/t/comp/package.t b/t/comp/package.t index d3e8850a4511..3f1d63702b5a 100644 --- a/t/comp/package.t +++ b/t/comp/package.t @@ -1,10 +1,5 @@ #!./perl -BEGIN { - @INC = qw(. ../lib); - chdir 't' if -d 't'; -} - print "1..14\n"; $blurfl = 123; @@ -19,10 +14,9 @@ $bar = 4; { package ABC; $blurfl = 5; - $main::a = $::b; + $main'a = $'b; } - -$ABC::dyick = 6; +$ABC'dyick = 6; $xyz = 2; @@ -36,7 +30,7 @@ if ('a' lt 'A') { print $xyz eq 'ABC:bar:main:new:xyz' ? "ok 1\n" : "not ok 1 '$xyz'\n"; } print $ABC eq 'blurfl:dyick' ? "ok 2\n" : "not ok 2 '$ABC'\n"; -print $main::blurfl == 123 ? "ok 3\n" : "not ok 3\n"; +print $main'blurfl == 123 ? "ok 3\n" : "not ok 3\n"; package ABC; diff --git a/t/comp/parser.t b/t/comp/parser.t index 14344cd686f0..20ecc7ac11c5 100644 --- a/t/comp/parser.t +++ b/t/comp/parser.t @@ -8,7 +8,7 @@ BEGIN { chdir 't' if -d 't'; } -print "1..189\n"; +print "1..191\n"; sub failed { my ($got, $expected, $name) = @_; @@ -222,12 +222,8 @@ EOF # tests for "Bad name" eval q{ foo::$bar }; like( $@, qr/Bad name after foo::/, 'Bad name after foo::' ); -{ - # since ' is no longer usable in symbols, the error is no longer "Bad name" - no warnings "syntax"; # suppress String found where operator expeected - eval q{ foo''bar }; - like( $@, qr/syntax error at \(eval \d+\) line 1, near "foo''/, 'Syntax error for foo\'' ); -} +eval q{ foo''bar }; +like( $@, qr/Bad name after foo'/, 'Bad name after foo\'' ); # test for ?: context error eval q{($a ? $x : ($y)) = 5}; @@ -372,11 +368,12 @@ like($@, qr/BEGIN failed--compilation aborted/, 'BEGIN 7' ); } { + no warnings; # [perl #113016] CORE::print::foo - sub CORE::print::foo { 43 } - sub CORE::foo::bar { 43 } + sub CORE'print'foo { 43 } # apostrophes intentional; do not tempt fate + sub CORE'foo'bar { 43 } is CORE::print::foo, 43, 'CORE::print::foo is not CORE::print ::foo'; - is scalar eval "CORE::foo::bar", 43, "CORE::foo'bar is not an error"; + is scalar eval "CORE::foo'bar", 43, "CORE::foo'bar is not an error"; } # bug #71748 @@ -454,6 +451,11 @@ END eval 's/${< ( EXPECT Bareword found where operator expected (Do you need to predeclare "isa"?) at - line 9, near "isa => 'Int" (Might be a runaway multi-line '' string starting on line 4) -syntax error at - line 9, near "isa => 'Int" -Execution of - aborted due to compilation errors. +Bad name after Int' at - line 9. ######## # NAME Bad name after :: (with other helpful messages) sub has{} @@ -613,17 +612,32 @@ syntax error at - line 2, near "[ (Might be a runaway multi-line // string starting on line 1) Execution of - aborted due to compilation errors. ######## -# NAME tick in names: initial character of sub name +# NAME tick in names: initial character of sub name (reverted) sub 'Hello'_he_said (_); EXPECT -Illegal declaration of anonymous subroutine at - line 1. +OPTIONS nonfatal +######## +# NAME tick in names: initial character of sub name (no feature) +no feature 'apostrophe_as_package_separator'; +sub 'Hello'_he_said (_); +EXPECT +Illegal declaration of anonymous subroutine at - line 2. +######## +# NAME tick in names: initial character of format name (reverted) + format 'one = +ok @<< - format 'foo still works +$test +. +EXPECT +OPTIONS nonfatal ######## -# NAME tick in names: initial character of format name +# NAME tick in names: initial character of format name (no feature_ +no feature 'apostrophe_as_package_separator'; format 'one = ok @<< - format 'foo still works $test . EXPECT -syntax error at - line 2, near "ok @<< - format '" - (Might be a runaway multi-line '' string starting on line 1) +syntax error at - line 3, near "ok @<< - format '" + (Might be a runaway multi-line '' string starting on line 2) Execution of - aborted due to compilation errors. diff --git a/t/lib/feature/api b/t/lib/feature/api index 5ad798dd7aa5..1635e3e60207 100644 --- a/t/lib/feature/api +++ b/t/lib/feature/api @@ -17,10 +17,10 @@ BEGIN { print "bundle: ", feature::feature_bundle(0) // "undef", "\n"; } EXPECT -default: bareword_filehandles indirect multidimensional +default: apostrophe_as_package_separator bareword_filehandles indirect multidimensional unicode_strings is not enabled bundle: default -5.12: bareword_filehandles indirect multidimensional say state unicode_strings +5.12: apostrophe_as_package_separator bareword_filehandles indirect multidimensional say state unicode_strings unicode_strings is enabled bundle: 5.11 ######## @@ -40,9 +40,9 @@ BEGIN { print "bundle: ", feature::feature_bundle(0) // "undef", "\n"; } EXPECT -no feature indirect: bareword_filehandles multidimensional +no feature indirect: apostrophe_as_package_separator bareword_filehandles multidimensional indirect is not enabled bundle: undef -added unicode_strings: bareword_filehandles multidimensional unicode_strings +added unicode_strings: apostrophe_as_package_separator bareword_filehandles multidimensional unicode_strings unicode_strings is enabled bundle: undef diff --git a/t/lib/feature/apos_as_pack_sep b/t/lib/feature/apos_as_pack_sep new file mode 100644 index 000000000000..657baaf481fc --- /dev/null +++ b/t/lib/feature/apos_as_pack_sep @@ -0,0 +1,34 @@ +Check apostrophe_as_package_separator feature + +__END__ +# NAME check default and 5.41 bundle +$foo'bar = 1; +use v5.41; +$foo'bar = 2; +EXPECT +OPTIONS fatal +Global symbol "$foo" requires explicit package name (did you forget to declare "my $foo"?) at - line 3. +Can't find string terminator "'" anywhere before EOF at - line 3. +######## +# NAME no feature apostrophe_as_package_separator +$foo'bar = 1; +no feature 'apostrophe_as_package_separator'; +$foo'bar = 2; +EXPECT +OPTIONS fatal +Can't find string terminator "'" anywhere before EOF at - line 3. +######## +# NAME use feature apostrophe_as_package_separator +use v5.41; +use feature 'apostrophe_as_package_separator'; +$foo'bar = 2; +$foo'bar = 3; # suppress used only once +EXPECT +######## +# NAME ' in symbolic refs always works and is treated as :: +my $x = "foo'bar"; +no feature 'apostrophe_as_package_separator'; +$$x = "Hello\n"; +print $foo::bar; +EXPECT +Hello diff --git a/t/lib/warnings/toke b/t/lib/warnings/toke index 476108858e21..6938174544fd 100644 --- a/t/lib/warnings/toke +++ b/t/lib/warnings/toke @@ -408,10 +408,46 @@ sort ("") EXPECT ######## -# NAME ' no longer is part of the symbol character set +@foo::bar = 1..3; +() = "$foo'bar"; +() = "@foo'bar"; +() = "$#foo'bar"; +use warnings 'syntax'; +() = "$foo'bar"; +() = "@foo'bar"; +() = "$#foo'bar"; +no warnings 'syntax', 'deprecated' ; +() = "$foo'bar"; +() = "@foo'bar"; +() = "$#foo'bar"; +# ' in names no longer deprecated, ensure we don't warn +EXPECT +######## +use warnings 'syntax'; use utf8; +@fooл::barл = 1..3; +() = "$fooл'barл"; +() = "@fooл'barл"; +() = "$#fooл'barл"; +no warnings 'syntax', 'deprecated' ; +() = "$fooл'barл"; +() = "@fooл'barл"; +() = "$#fooл'barл"; +# ' in names no longer deprecated, ensure we don't warn +EXPECT +######## +# NAME deprecation of ' in names reverted +sub foo'bar { 1 } +$a'b = 1; +@a'c = (); +%a'd = (); +package a'e; +# ' in names no longer deprecated, ensure we don't warn +EXPECT +######## +# NAME ' no longer is part of the symbol character set (reverted) # previously these would parse like: -# "${foo'bar}", but now they parse like "${foo}'bar" -# and any ' parsing for symbols is now gone, so no warning +# "${foo'bar}", but they did parse like "${foo}'bar" +# but now they parse in names again @foo::bar = 1..3; () = "$foo'bar"; () = "@foo'bar"; @@ -437,17 +473,14 @@ no warnings 'syntax', 'deprecated' ; () = "@fooл'barл"; () = "$#fooл'barл"; EXPECT -Possible unintended interpolation of @fooл in string at - line 5. ######## -# NAME deprecation of ' in names +# NAME deprecation of ' in names (reverted) sub foo'bar { 1 } $a'b = 1; @a'c = (); %a'd = (); package a'e; EXPECT -OPTION fatal -Illegal declaration of subroutine main::foo at - line 1. ######## # toke.c use warnings 'ambiguous' ; diff --git a/t/op/magic.t b/t/op/magic.t index d13b6c5d8018..49e39b7c7203 100644 --- a/t/op/magic.t +++ b/t/op/magic.t @@ -5,7 +5,7 @@ BEGIN { chdir 't' if -d 't'; require './test.pl'; set_up_inc( '../lib' ); - plan (tests => 209); # some tests are run in BEGIN block + plan (tests => 208); # some tests are run in BEGIN block } # Test that defined() returns true for magic variables created on the fly, @@ -676,14 +676,6 @@ foreach my $sig (qw(__WARN__ INT)) { is delete $SIG{$sig}, undef, "$sig remains gone"; } -# test Perl_magic_setsig main:: qualification -# this previously did it for names containing ' -{ - local $SIG{INT} = "foo'bar"; - is($SIG{INT}, "main::foo'bar", - "' in signal handler name no longer a package separator"); -} - # And now one which doesn't exist; { no warnings 'signal'; diff --git a/t/op/method.t b/t/op/method.t index ddadb87420e6..eaa129aee1c7 100644 --- a/t/op/method.t +++ b/t/op/method.t @@ -13,7 +13,7 @@ BEGIN { use strict; no warnings 'once'; -plan(tests => 161); +plan(tests => 163); { # RT #126042 &{1==1} * &{1==1} would crash @@ -253,6 +253,12 @@ sub OtherSouper::method { "Isidore Ropen, Draft Manager" } my @ret = $o->SUPER::method('whatever'); ::is $ret[0], $o, 'object passed to SUPER::method'; ::is $ret[1], 'whatever', 'argument passed to SUPER::method'; + { + no warnings qw(syntax deprecated); + @ret = $o->SUPER'method('whatever'); + } + ::is $ret[0], $o, "object passed to SUPER'method"; + ::is $ret[1], 'whatever', "argument passed to SUPER'method"; @ret = Saab->SUPER::method; ::is $ret[0], 'Saab', "package name passed to SUPER::method"; @ret = OtherSaab->SUPER::method; diff --git a/t/op/ref.t b/t/op/ref.t index 76b55b24ad9d..3cf6ab047259 100644 --- a/t/op/ref.t +++ b/t/op/ref.t @@ -272,8 +272,10 @@ is (join('', sort values %$anonhash2), 'BARXYZ'); # Test bless operator. package MYHASH; -$object = bless $main::anonhash2; - +{ + no warnings qw(syntax deprecated); + $object = bless $main'anonhash2; +} main::is (ref $object, 'MYHASH'); main::is ($object->{ABC}, 'XYZ'); @@ -297,7 +299,10 @@ sub mymethod { $string = "bad"; $object = "foo"; $string = "good"; -$main::anonhash2 = "foo"; +{ + no warnings qw(syntax deprecated); + $main'anonhash2 = "foo"; +} $string = ""; DESTROY { @@ -314,7 +319,10 @@ package OBJ; @ISA = ('BASEOBJ'); -$main::object = bless {FOO => 'foo', BAR => 'bar'}; +{ + no warnings qw(syntax deprecated); + $main'object = bless {FOO => 'foo', BAR => 'bar'}; +} package main; @@ -327,10 +335,13 @@ is ($object->doit("BAR"), 'bar'); $foo = doit $object "FOO"; main::is ($foo, 'foo'); -sub BASEOBJ::doit { - local $ref = shift; - die "Not an OBJ" unless ref $ref eq 'OBJ'; - $ref->{shift()}; +{ + no warnings qw(syntax deprecated); + sub BASEOBJ'doit { + local $ref = shift; + die "Not an OBJ" unless ref $ref eq 'OBJ'; + $ref->{shift()}; + } } package UNIVERSAL; diff --git a/t/op/sort.t b/t/op/sort.t index 19c99961ac05..bdb965dcee63 100644 --- a/t/op/sort.t +++ b/t/op/sort.t @@ -240,7 +240,7 @@ eval <<'CODE'; no warnings qw(deprecated syntax); my @result = sort main'Backwards 'one', 'two'; CODE -cmp_ok($@,'ne','',q(old skool package)); +cmp_ok($@,'eq','',q(old skool package)); eval <<'CODE'; # "sort 'one', 'two'" should not try to parse "'one" as a sort sub diff --git a/t/op/stash.t b/t/op/stash.t index f10834adcc87..a507c4239db1 100644 --- a/t/op/stash.t +++ b/t/op/stash.t @@ -6,7 +6,7 @@ BEGIN { set_up_inc( qw(../lib) ); } -plan( tests => 54 ); +plan( tests => 55 ); # Used to segfault (bug #15479) fresh_perl_like( @@ -301,6 +301,10 @@ fresh_perl_is( 'packages ending with :: are self-consistent'; } +# [perl #88138] ' not equivalent to :: before a null +${"a'\0b"} = "c"; +is ${"a::\0b"}, "c", "' is equivalent to :: before a null"; + # [perl #101486] Clobbering the current package ok eval ' package Do; diff --git a/t/op/stash_parse_gv.t b/t/op/stash_parse_gv.t index 465480e331eb..9e143d979e15 100644 --- a/t/op/stash_parse_gv.t +++ b/t/op/stash_parse_gv.t @@ -6,7 +6,7 @@ BEGIN { set_up_inc(qw(../lib)); } -plan( tests => 3 ); +plan( tests => 5 ); my $long = 'x' x 100; my $short = 'abcd'; @@ -14,7 +14,9 @@ my $short = 'abcd'; my @tests = ( [ $long, 'long package name: one word' ], [ join( '::', $long, $long ), 'long package name: multiple words' ], + [ join( q['], $long, $long ), q[long package name: multiple words using "'" separator] ], [ join( '::', $long, $short, $long ), 'long & short package name: multiple words' ], + [ join( q['], $long, $short, $long ), q[long & short package name: multiple words using "'" separator] ], ); foreach my $t (@tests) { diff --git a/t/uni/package.t b/t/uni/package.t index b615bf01120a..d4e69ca38044 100644 --- a/t/uni/package.t +++ b/t/uni/package.t @@ -9,6 +9,9 @@ BEGIN { plan (tests => 18); +# Works on either ASCII or EBCDIC +my $prefix = ("a" lt "A") ? "bar:BEGIN" : "BEGIN:bar"; + use utf8; use open qw( :utf8 :std ); @@ -34,17 +37,23 @@ ok 1, "sanity check. If we got this far, UTF-8 in package names is legal."; $ㄅĽuṞfⳐ = 5; } - $압Ƈ::d읯ⱪ = 6; + { + no warnings qw(syntax deprecated); + $압Ƈ'd읯ⱪ = 6; #' + } $ꑭʑ = 2; $ꑭʑ = join(':', sort(keys %ꑭʑ::)); $압Ƈ = join(':', sort(keys %압Ƈ::)); - ::is $ꑭʑ, "bar:ニュー:ꑭʑ:압Ƈ", "comp/stash.t test 1"; + ::is $ꑭʑ, "$prefix:ニュー:ꑭʑ:압Ƈ", "comp/stash.t test 1"; ::is $압Ƈ, "d읯ⱪ:ㄅĽuṞfⳐ", "comp/stash.t test 2"; - ::is $main::ㄅĽuṞfⳐ, 123, "comp/stash.t test 3"; + { + no warnings qw(syntax deprecated); + ::is $main'ㄅĽuṞfⳐ, 123, "comp/stash.t test 3"; + } package 압Ƈ; diff --git a/t/uni/parser.t b/t/uni/parser.t index 6fdd99749163..d3aa74527224 100644 --- a/t/uni/parser.t +++ b/t/uni/parser.t @@ -187,12 +187,8 @@ is ${"main::\345\225\217"}, undef, "..and using the encoded form doesn't"; # tests for "Bad name" eval q{ Foo::$bar }; like( $@, qr/Bad name after Foo::/, 'Bad name after Foo::' ); -{ - # since ' is no longer usable in symbols, the error is no longer "Bad name" - no warnings "syntax"; # suppress String found where operator expeected - eval q{ Foo''bar }; - like( $@, qr/syntax error at \(eval \d+\) line 1, near \"Foo\'\'/, 'Syntax error for Foo\'' ); -} +eval q{ Foo''bar }; +like( $@, qr/Bad name after Foo'/, 'Bad name after Foo\'' ); { no warnings 'utf8'; diff --git a/t/uni/stash.t b/t/uni/stash.t index 7bfdc6cac3c5..a069aa111e23 100644 --- a/t/uni/stash.t +++ b/t/uni/stash.t @@ -13,7 +13,7 @@ BEGIN { use utf8; use open qw( :utf8 :std ); -plan( tests => 48 ); +plan( tests => 49 ); #These come from op/my_stash.t { @@ -283,4 +283,8 @@ plan( tests => 48 ); ok eval { Bèàr::::bàz() }, 'packages ending with :: are self-consistent'; } + + # [perl #88138] ' not equivalent to :: before a null + ${"à'\0b"} = "c"; + is ${"à::\0b"}, "c", "' is equivalent to :: before a null"; } diff --git a/t/uni/variables.t b/t/uni/variables.t index c5284de3e9f5..2c18951a1a26 100644 --- a/t/uni/variables.t +++ b/t/uni/variables.t @@ -14,7 +14,7 @@ use utf8; use open qw( :utf8 :std ); no warnings qw(misc reserved); -plan (tests => 66879); +plan (tests => 66880); # ${single:colon} should not be treated as a simple variable, but as a # block with a label inside. @@ -35,11 +35,16 @@ plan (tests => 66879); ); } -# and ${yadda::etc} should both work under strict +# ${yadda'etc} and ${yadda::etc} should both work under strict { local $@; eval q; is($@, '', q<${package::var} works>); + + no warnings qw(syntax deprecated); + local $@; + eval q; + is($@, '', q<...as does ${package'var}>); } # The first character in ${...} should respect the rules diff --git a/toke.c b/toke.c index 0ff92d2b256f..22ba91f6cffb 100644 --- a/toke.c +++ b/toke.c @@ -5585,6 +5585,7 @@ yyl_sub(pTHX_ char *s, const int key) PL_parser->sig_seen = FALSE; if ( isIDFIRST_lazy_if_safe(s, PL_bufend, UTF) + || (*s == '\'' && FEATURE_APOS_AS_NAME_SEP_IS_ENABLED) || (*s == ':' && s[1] == ':')) { @@ -7701,7 +7702,8 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 orig_keyword, struct code c) /* Get the rest if it looks like a package qualifier */ - if (*s == ':' && s[1] == ':') { + if ((*s == '\'' && FEATURE_APOS_AS_NAME_SEP_IS_ENABLED) + || (*s == ':' && s[1] == ':')) { STRLEN morelen; s = scan_word(s, PL_tokenbuf + len, sizeof PL_tokenbuf - len, TRUE, &morelen); @@ -7710,8 +7712,9 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 orig_keyword, struct code c) no_op_error = FALSE; } if (!morelen) - Perl_croak(aTHX_ "Bad name after %" UTF8f "::", - UTF8fARG(UTF, len, PL_tokenbuf)); + Perl_croak(aTHX_ "Bad name after %" UTF8f "%s", + UTF8fARG(UTF, len, PL_tokenbuf), + *s == '\'' ? "'" : "::"); len += morelen; pkgname = 1; } @@ -8856,17 +8859,19 @@ yyl_word_or_keyword(pTHX_ char *s, STRLEN len, I32 key, I32 orig_keyword, struct static int yyl_key_core(pTHX_ char *s, STRLEN len, struct code c) { + I32 key = 0; I32 orig_keyword = 0; STRLEN olen = len; char *d = s; s += 2; s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len); - if (*s == ':' && s[1] == ':') + if ((*s == ':' && s[1] == ':') + || (!(key = keyword(PL_tokenbuf, len, 1)) && *s == '\'' && + FEATURE_APOS_AS_NAME_SEP_IS_ENABLED)) { Copy(PL_bufptr, PL_tokenbuf, olen, char); return yyl_just_a_word(aTHX_ d, olen, 0, c); } - I32 key = keyword(PL_tokenbuf, len, 1); if (!key) Perl_croak(aTHX_ "CORE::%" UTF8f " is not a keyword", UTF8fARG(UTF, len, PL_tokenbuf)); @@ -10297,6 +10302,15 @@ S_parse_ident(pTHX_ char **s, char **d, char * const e, int allow_package, *(*d)++ = *(*s)++; } while (isWORDCHAR_A(**s) && *d < e); } + else if ( allow_package + && **s == '\'' + && FEATURE_APOS_AS_NAME_SEP_IS_ENABLED + && isIDFIRST_lazy_if_safe((*s)+1, PL_bufend, is_utf8)) + { + *(*d)++ = ':'; + *(*d)++ = ':'; + (*s)++; + } else if (allow_package && **s == ':' && (*s)[1] == ':' /* Disallow things like Foo::$bar. For the curious, this is * the code path that triggers the "Bad name after" warning @@ -11434,7 +11448,8 @@ S_scan_inputsymbol(pTHX_ char *start) if (*d == '$' && d[1]) d++; /* allow or */ - while (isWORDCHAR_lazy_if_safe(d, e, UTF) || *d == ':') { + while (isWORDCHAR_lazy_if_safe(d, e, UTF) || *d == ':' + || (*d == '\'' && FEATURE_APOS_AS_NAME_SEP_IS_ENABLED)) { d += UTF ? UTF8SKIP(d) : 1; } diff --git a/warnings.h b/warnings.h index 3322ed821b6c..e4897b655beb 100644 --- a/warnings.h +++ b/warnings.h @@ -150,21 +150,17 @@ #define WARN_EXPERIMENTAL__CLASS 75 -/* Warnings Categories added in Perl 5.037009 */ - -#define WARN_DEPRECATED__APOSTROPHE_AS_PACKAGE_SEPARATOR 76 - /* Warnings Categories added in Perl 5.03701 */ -#define WARN_DEPRECATED__SMARTMATCH 77 +#define WARN_DEPRECATED__SMARTMATCH 76 /* Warnings Categories added in Perl 5.039002 */ -#define WARN_DEPRECATED__MISSING_IMPORT_CALLED_WITH_ARGS 78 +#define WARN_DEPRECATED__MISSING_IMPORT_CALLED_WITH_ARGS 77 /* Warnings Categories added in Perl 5.039008 */ -#define WARN_DEPRECATED__SUBSEQUENT_USE_VERSION 79 +#define WARN_DEPRECATED__SUBSEQUENT_USE_VERSION 78 #define WARNsize 20 #define WARN_ALLstring "\125\125\125\125\125\125\125\125\125\125\125\125\125\125\125\125\125\125\125\125" #define WARN_NONEstring "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" @@ -355,7 +351,6 @@ category parameters passed. =for apidoc Amnh||WARN_DEPRECATED__VERSION_DOWNGRADE =for apidoc Amnh||WARN_DEPRECATED__DELIMITER_WILL_BE_PAIRED =for apidoc Amnh||WARN_EXPERIMENTAL__CLASS -=for apidoc Amnh||WARN_DEPRECATED__APOSTROPHE_AS_PACKAGE_SEPARATOR =for apidoc Amnh||WARN_DEPRECATED__SMARTMATCH =for apidoc Amnh||WARN_DEPRECATED__MISSING_IMPORT_CALLED_WITH_ARGS =for apidoc Amnh||WARN_DEPRECATED__SUBSEQUENT_USE_VERSION