Skip to content

Remove return.missing baseline and fix its issue - #13082

Closed
dpanta94 wants to merge 4 commits into
WordPress:trunkfrom
dpanta94:fix/phpstan-baselines.7
Closed

Remove return.missing baseline and fix its issue#13082
dpanta94 wants to merge 4 commits into
WordPress:trunkfrom
dpanta94:fix/phpstan-baselines.7

Conversation

@dpanta94

@dpanta94 dpanta94 commented Aug 16, 2026

Copy link
Copy Markdown

✅ Committed in:


Removes in total 41 errors.

Removes errors from the below phpstan baselines and fixes the issues that they were covering:

  • return.missing

How ?

Adds return types according to method docblocks.

Trac ticket: https://core.trac.wordpress.org/ticket/65817

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Opus 5
Used for: Help with suggesting how to fix the phpstan output for the specific errors we are removing the baselines for. The actual result has been reviewed and are owned by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props dpantazis, westonruter, dmsnell.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@dmsnell dmsnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a number of mixed categories of missing returns, this PR is probably too big to merge as a single change. Could we split it into those which should be benign by simply adding a missing return null; as the last statement in a function, from those which involve Docblock changes, from those which rearrange the return code (e.g. general-template.php, with the $display check).

those last ones seem trivial, but I fear from experience that it’s easy to accidentally flip a boolean and then introduce a regression

westonruter and others added 2 commits August 27, 2026 13:44
Resolve the conflict in the generated baseline include list in
`phpstan.neon.dist`. Each side deleted a different baseline: this branch
removed `return.missing.neon`, while trunk removed `return.empty.neon`.
Both removals are kept, so neither include line survives and the list
again matches the contents of `tests/phpstan/baselines/`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The annotation had been widened to `string|null|void`, but the `null` there is
inert. PHPStan resolves `string|null|void` and `string|void` to the same
call-site type, `string|null`, and suppresses `return.missing` on overrides in
both cases; only `string|null` on its own makes the return obligatory. The
union therefore behaved exactly as `string|void` while reading as though the
stricter `null` spelling had been chosen.

That distinction matters for this method. The base implementation echoes a
notice and returns 'noform', while the 18 subclass overrides echo their own
markup and fall off the end, four of them in bundled themes. `void` is the
accurate description of that contract, and the one that keeps the overrides
compliant.

`string|null|void` was also the only union in `src/` to combine `null` and
`void`, and it ordered `void` last where 45 of the 47 surviving `void` unions
in core put it first.

Matches the wording already used for this method on the
`fix/phpstan-7.1-regressions` branch, and drops the blank line that had been
inserted between `@param` and `@return`, which was the only such gap in the
file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@westonruter

Copy link
Copy Markdown
Member

this PR is probably too big to merge as a single change

I'm preparing to make multiple commits for this.

pento pushed a commit that referenced this pull request Aug 27, 2026
PHPStan reports `return.missing` where a documented return type obliges a function to return a value on every path, but one path falls off the end instead. Adding the `return null;` that the annotation already implies resolves the report without changing behavior, since PHP was returning null implicitly anyway. This is the shape r61716 used on `get_category_by_path()`, which replaced a bare `return;` in that same function; its remaining path is now handled too.

Covered here are `get_category_by_path()`, `wp_list_users()`, `single_month_title()`, `WP_Customize_Manager::get_setting()`, `get_panel()`, `get_section()` and `get_control()`, `WP_Customize_Widgets::get_setting_type()`, `WP_Customize_Header_Image_Control::get_current_image_src()`, `WP_Image_Editor_Imagick::set_imagick_time_limit()`, and the four pagination helpers in `link-template.php`.

Every change is a pure append, leaving the diff additive at 30 insertions and no deletions. Two further groups of `return.missing` fixes from the same pull request carry more risk and will follow separately.

The baseline `tests/phpstan/baselines/return.missing.neon` drops from 41 entries covering 44 errors to 27 covering 29, so the file and its entry in `phpstan.neon.dist` both remain for now.

Developed in #13082.
Follow-up to r61716, r63020.

Props dpantazis, dmsnell.
See #65817.


git-svn-id: https://develop.svn.wordpress.org/trunk@63378 602fd350-edb4-49c9-b593-d223f7449a82
@westonruter

Copy link
Copy Markdown
Member

OK, I committed the adding of the missing return null in r63378 (5bf6381).

Proceeding to merge trunk into this branch for the remaining changes.

Brings in r63369 through r63378, which includes the first of this branch's
three groups of `return.missing` fixes: the 14 pure `return null;` appends
landed on trunk as r63378, so they drop out of the branch's remaining diff.

Resolve the modify/delete conflict on
`tests/phpstan/baselines/return.missing.neon` in favour of the deletion. Trunk
shrank the file to the 27 entries the appends did not cover; this branch still
carries the fixes for all of them, so the file reaches zero and goes, taking
its `phpstan.neon.dist` entry with it. Regenerating every baseline confirms it:
`return.missing` no longer appears among the generated files, and no other
baseline moved.

What remains against trunk is the two groups held back for separate review, the
`WP_Widget::form()` return type and the `$display` branch inversions in
`general-template.php` and `link-template.php`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Aug 27, 2026
PHPStan reports `return.missing` where a documented return type obliges a function to return a value on every path, but one path falls off the end instead. Adding the `return null;` that the annotation already implies resolves the report without changing behavior, since PHP was returning null implicitly anyway. This is the shape r61716 used on `get_category_by_path()`, which replaced a bare `return;` in that same function; its remaining path is now handled too.

Covered here are `get_category_by_path()`, `wp_list_users()`, `single_month_title()`, `WP_Customize_Manager::get_setting()`, `get_panel()`, `get_section()` and `get_control()`, `WP_Customize_Widgets::get_setting_type()`, `WP_Customize_Header_Image_Control::get_current_image_src()`, `WP_Image_Editor_Imagick::set_imagick_time_limit()`, and the four pagination helpers in `link-template.php`.

Every change is a pure append, leaving the diff additive at 30 insertions and no deletions. Two further groups of `return.missing` fixes from the same pull request carry more risk and will follow separately.

The baseline `tests/phpstan/baselines/return.missing.neon` drops from 41 entries covering 44 errors to 27 covering 29, so the file and its entry in `phpstan.neon.dist` both remain for now.

Developed in WordPress/wordpress-develop#13082.
Follow-up to r61716, r63020.

Props dpantazis, dmsnell.
See #65817.

Built from https://develop.svn.wordpress.org/trunk@63378


git-svn-id: http://core.svn.wordpress.org/trunk@62571 1a063a9b-81f0-0310-95a4-ce76da25c4cd
pento pushed a commit that referenced this pull request Aug 27, 2026
Nine template functions take a `$display` parameter and either echo their result or return it. Each is documented as returning `string|null`, but the echoing branch fell off the end without returning, which is what PHPStan reports as `return.missing`. Inverting the condition lets the value-returning path exit first and the echoing path fall through to an explicit `return null;`, the same shape `single_month_title()` received in r63378. Affected are `wp_title()`, `single_post_title()`, `post_type_archive_title()`, `single_term_title()`, `the_date()`, `the_modified_date()`, `edit_term_link()`, `next_posts()` and `previous_posts()`. No behavior changes.

`WP_Widget::form()` is documented as `string|void` again. r59336 added the `void` deliberately, noting that unlike its siblings it is the child classes which return nothing when the method is correctly implemented. r62178 replaced it with `null` on the premise that `void` cannot belong to a union, which holds for PHP's native return types but not for PHPDoc, where PHPStan reads `void` in a union as "may not return at all". Under `string|null` the annotation instead obliged every override to return, putting all 18 of them in breach, two of which live in bundled themes that r62178 did not touch.

With no occurrences left, `tests/phpstan/baselines/return.missing.neon` is deleted along with its entry in `phpstan.neon.dist`, completing the work begun in r63378.

Developed in #13082.
Follow-up to r59336, r62178, r63020, r63378.

Props dpantazis, dmsnell.
See #65817, #64704.


git-svn-id: https://develop.svn.wordpress.org/trunk@63379 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Aug 27, 2026
Nine template functions take a `$display` parameter and either echo their result or return it. Each is documented as returning `string|null`, but the echoing branch fell off the end without returning, which is what PHPStan reports as `return.missing`. Inverting the condition lets the value-returning path exit first and the echoing path fall through to an explicit `return null;`, the same shape `single_month_title()` received in r63378. Affected are `wp_title()`, `single_post_title()`, `post_type_archive_title()`, `single_term_title()`, `the_date()`, `the_modified_date()`, `edit_term_link()`, `next_posts()` and `previous_posts()`. No behavior changes.

`WP_Widget::form()` is documented as `string|void` again. r59336 added the `void` deliberately, noting that unlike its siblings it is the child classes which return nothing when the method is correctly implemented. r62178 replaced it with `null` on the premise that `void` cannot belong to a union, which holds for PHP's native return types but not for PHPDoc, where PHPStan reads `void` in a union as "may not return at all". Under `string|null` the annotation instead obliged every override to return, putting all 18 of them in breach, two of which live in bundled themes that r62178 did not touch.

With no occurrences left, `tests/phpstan/baselines/return.missing.neon` is deleted along with its entry in `phpstan.neon.dist`, completing the work begun in r63378.

Developed in WordPress/wordpress-develop#13082.
Follow-up to r59336, r62178, r63020, r63378.

Props dpantazis, dmsnell.
See #65817, #64704.

Built from https://develop.svn.wordpress.org/trunk@63379


git-svn-id: http://core.svn.wordpress.org/trunk@62572 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@IanDelMar

Copy link
Copy Markdown

@dpanta94 I think the resolved void unions in the functions using a $display parameter were less a type-system problem than a conceptual/API-design issue. These functions combine two responsibilities: depending on the argument, they either output a result or return one. That dual behaviour is what was causing the void unions in the first place.

Replacing void with null avoids the union, but it removed information that PHPStan otherwise could have used. Although the runtime value is still effectively null, PHPStan can no longer detect the logical error of consuming a meaningless value. And errors like Result of function function_name (void) is used. will no longer be raised, because null is now treated as a legitimate return value. See this example: https://phpstan.org/r/2c79437a-f917-4cce-8d28-1eca46bd2fa6

I understand and support the effort to get rid of the void unions but I am not sure that replacing void with null in this context is an improvement from a static-analysis perspective.

cc @westonruter

@westonruter

Copy link
Copy Markdown
Member

@IanDelMar Thank you for following up on this. I've opened #13359 to apply this feedback.

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.

4 participants