September 21, 2018·4 min read·engineeringperlcompilerdiagnostics

Perl 5.29.3 removes misleading constant-folding warnings

Perl 5.29.3 corrects spurious warnings involving overloaded constants and repairs an assignment followed by concatenation.

Compiler work can invoke behaviour supplied by a Perl module, so a warning produced during constant folding is not necessarily a simple report about a literal value. Perl 5.29.3 fixes spurious uninitialized-value warnings associated with warnings from constant-folding operations on overloaded values. Its release notes identify this as issue 132683. The distinction matters because a misleading secondary warning can direct investigation towards a value that is not the problem.

John SJ Anderson published the release announcement on September 21. This development release also repairs a lexical assignment followed by concatenating assignment. Both fixes concern the interaction between familiar expressions and interpreter processing that application source does not spell out explicitly.

I appreciate Perl when a short expression makes a text operation easy to write. Correct diagnostics help keep that compactness manageable. When the compiler reports an uninitialized value spuriously, the reader has to question both the expression and the report intended to explain it.

Constants can involve module code

The overload documentation shipped with this release describes hooks into the parsing of constants through overload::constant() and overload::remove_constant(). Supported categories include integer and floating-point constants, octal and hexadecimal constants, and constant pieces of quoted strings or regular expressions. A constant in source can therefore participate in module-defined interpretation.

The callback receives the original string form, Perl interpretation of that constant, and information about its use. Its return value becomes the interpretation Perl uses. That arrangement allows a module to preserve or reinterpret information that ordinary parsing would otherwise transform. It also means compiler operations can encounter values with behaviour supplied by that module.

The documentation makes the connection to concatenation explicit. An interpolated string includes constant pieces joined to variable expressions. When a module overloads constant strings, the documentation expects the resulting values to have reasonable overloaded concatenation behaviour. Otherwise the ordinary construction of an interpolated string can produce unsuitable results.

Negative numbers introduce another relationship. The documentation describes them as negations of positive constants. Overloading the interpretation of the positive constant therefore interacts with the operation applied to it. A literal-looking expression can involve more than one operation whose behaviour depends on a module.

These facilities explain why constant folding and overloading need to cooperate. The compiler cannot simply assume that every value encountered during work on constants is an ordinary built-in scalar with no associated behaviour. At the same time, the language still needs to produce diagnostics that accurately identify the operation and condition involved.

The release notes describe removal of a spurious uninitialized-value warning, rather than suppression of all warnings from overloaded constant operations. That scope is important. A legitimate warning from the operation may still convey useful information. The repair concerns the misleading warning produced alongside it, and the notes do not justify treating every diagnostic in such code as erroneous.

Optimizations can introduce assignment forms

The same overload manual warns that the optimizer can generate assignment variants of operations even where source code does not explicitly contain them. Its example turns an interpolated expression into construction of a temporary string followed by concatenating assignment. A module supplying overloaded concatenation can therefore encounter forms arising from interpreter transformations.

This makes the distinction between concatenation and concatenating assignment relevant to extension authors. Source syntax alone does not enumerate every operation the optimizer may use internally. An implementation of overloading needs to respect the documented behaviour of those generated forms, including the handling of references and assignment results.

The release notes separately list a fix for the internal error described as mutator not seen in (lex = ...) .= ..., under issue 133441. That description identifies an expression combining lexical assignment with a subsequent concatenating update. The notes do not provide a complete reproducer, so they support the stated shape of the repaired failure without establishing that every such expression failed.

Together these changes illustrate a boundary that compact source code can conceal. A compiler can reorganize operations, and overloaded values can execute module code when those operations occur. Correctness includes the resulting value, but also the absence of false diagnostics and internal errors along the way. A repair can be useful without adding a new language construct.

Core availability is a separate compatibility question

Perl 5.29.3 also removes Locale::Codes from the core distribution at its author request. The release notes say the module remains available on CPAN. This is a packaging change, so code that depends on the module needs to distinguish its availability from whether the interpreter itself implements a language feature.

That change differs from the warning repair. An application can receive the corrected constant-folding behaviour through its interpreter while needing to install a previously bundled module separately. Treating every development-release difference as an alteration of expression semantics would miss that dependency issue.

I prefer release notes that make these distinctions visible. This release identifies a diagnostic bug, a concatenation failure, and a module-distribution change independently. For code using overloaded constants, the immediate improvement is a more accurate report of what happened during compiler processing, with the separate dependency change handled through the module installation process.