Skip to content

Treat mb_str_pad() as side-effect-free like other mbstring string functions - #6441

Open
zonuexe wants to merge 1 commit into
phpstan:2.2.xfrom
zonuexe:align-mbstring-string-function-purity
Open

zonuexe wants to merge 1 commit into
phpstan:2.2.xfrom
zonuexe:align-mbstring-string-function-purity

Conversation

@zonuexe

@zonuexe zonuexe commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Among the mbstring string-processing functions in the issue's reproducer, phpstorm-stubs marks mb_str_pad() as #[Pure(true)], while comparable functions such as mb_strlen(), mb_strcut(), and mb_trim() are marked #[Pure]. The metadata generator therefore emits hasSideEffects => true for mb_str_pad only, so @phpstan-pure functions cannot call it.

This change treats mb_str_pad as hasSideEffects => false so it matches those siblings.

This is a pragmatic override, not a claim that the function is theoretically pure. The result can change if the analysed program changes internal encoding (mb_internal_encoding() or default_charset). PHPStan does not track encoding-state changes made by the analysed program. Some existing return-type extensions (mb_strlen() and mb_str_split()) use the analyser process's mb_internal_encoding() when the encoding argument is omitted; mb_str_pad() itself has no dedicated return-type extension. Encoding-dependent purity (explicit encoding = pure, omitted = impure) remains out of scope.

This is not the same rationale as the ob_get_level() exception in #6439: PHPStan models output-buffer level changes, but it does not model the encoding state that affects mb_str_pad(). This override is an explicit consistency trade-off, not a scope-managed-state optimization.

functionMetadata_original.php records this project-specific policy, while the generator special case prevents phpstorm-stubs' current #[Pure(true)] annotation from rejecting or reversing it during regeneration.

Applying functionMetadata on BetterReflection's fallback path is not done here: name-keyed built-in metadata can leak to user polyfills and unrelated built-ins. This PR does not change the pre-existing cross-version discovery of PHP 8.4-only mbstring names under phpVersion: 8.3.

Addresses Issue 1 in phpstan/phpstan#15224. Issue 2 (encoding-sensitive purity) remains open and is not addressed by this PR.

Made with Cursor

@zonuexe
zonuexe marked this pull request as draft September 14, 2026 11:27
@zonuexe zonuexe changed the title Treat mbstring string-processing functions as pure consistently Treat mb_str_pad as side-effect-free like other mbstring string functions Sep 14, 2026
Override phpstorm-stubs' #[Pure(true)] classification so mb_str_pad() is handled like comparable mbstring string-processing functions. This enables pure-function checks, unused-result diagnostics, and repeated-call narrowing without changing BetterReflection fallback metadata handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zonuexe
zonuexe force-pushed the align-mbstring-string-function-purity branch from f1bac43 to 0483215 Compare September 14, 2026 12:33
@zonuexe zonuexe changed the title Treat mb_str_pad as side-effect-free like other mbstring string functions Treat mb_str_pad() as side-effect-free like other mbstring string functions Sep 14, 2026
@zonuexe
zonuexe marked this pull request as ready for review September 14, 2026 13:05
@phpstan-bot

Copy link
Copy Markdown
Collaborator

This pull request has been marked as ready for review.

@staabm

staabm commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

I sent a comment into phpstorm stubs, as the inconsistency for mb_str_pad vs. all other functions was created on that end, and it does not really make sense IMO.

see JetBrains/phpstorm-stubs#1836

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants