Inconsistency in PHP 8.5 deprecation of terminating case with semicolon

php.internals

Unnamed Person

321 days ago
Dear Theodore and list, I've been looking into the "Deprecate semicolon after case in switch statement" PHP 8.5 deprecation [1] with the aim of adding a sniff for this to the PHPCompatibility standard and I'm noticing an oddity for which I would like to clarify whether this is intentional or an oversight. As demonstrated in the example code provided in the deprecation RFC, both switch `case` condition statements, as well as `default` statements, can be ended with a semicolon. So when I first read the RFC, I interpreted the proposal to include both `case` as well as `default`, as, in my mind, `default` is just a special `case` in a switch. However, the RFC explicitly only talked about deprecating the use of a semicolon after a `case` statement and the implementation has followed this to the letter. [2] The net result of this, is that you can now have a `switch` statement with semicolons terminating `case` statements and `default` statements, where the former (`case`) will result in a deprecation notice, while the latter (`default`) will not. For an example, see [3] This feels inconsistent to me and counter to the intention of the RFC, which is stated to be:
> Case statements followed by a semicolon can cause confusion, as a
developer may think they behave differently in some way from regular case statements (e.g. preventing fallthrough), when they do not. Which leaves me wondering what the reason was not to _also_ deprecate the use of a semicolon to terminate a `default` statement in a switch ? I can't find any discussion about this in the original mailing list thread [4]. Anyone would care to clarify ? Smile, Juliette 1: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_semicolon_after_case_in_switch_statement 2: https://github.com/php/php-src/commit/5f8d648af6ef4e29a3c7f2b2029d08466c12bc6f 3: https://3v4l.org/liFIK/rfc#vgit.master 4: https://externals.io/message/126000

Theodore Brown

321 days ago
On Tue, October 14 2025 at 18:08 Juliette Reinders Folmer wrote: > Dear Theodore and list, > > I've been looking into the "Deprecate semicolon after case in switch statement" PHP 8.5 deprecation [1] > with the aim of adding a sniff for this to the PHPCompatibility standard and I'm noticing an oddity for > which I would like to clarify whether this is intentional or an oversight. > > As demonstrated in the example code provided in the deprecation RFC, both switch `case` condition > statements, as well as `default` statements, can be ended with a semicolon. > > So when I first read the RFC, I interpreted the proposal to include both `case` as well as `default`, > as, in my mind, `default` is just a special `case` in a switch. > > However, the RFC explicitly only talked about deprecating the use of a semicolon after a > `case` statement and the implementation has followed this to the letter. [2] > > The net result of this, is that you can now have a `switch` statement with semicolons > terminating `case` statements and `default` statements, where the former (`case`) will > result in a deprecation notice, while the latter (`default`) will not. For an example, see [3] > > This feels inconsistent to me and counter to the intention of the RFC, which is stated to be: > >> Case statements followed by a semicolon can cause confusion, as a developer may think they >> behave differently in some way from regular case statements (e.g. preventing fallthrough), >> when they do not. > > Which leaves me wondering what the reason was not to _also_ deprecate the use of a semicolon > to terminate a `default` statement in a switch ? I can't find any discussion about this in the > original mailing list thread [4]. > > Anyone would care to clarify ? Hi Juliette, Thank you for pointing out the discrepancy. You are correct that `default` is just a special case statement, and the intention in the RFC was to output the deprecation message for default cases as well (the example in the RFC included a default case followed by a semicolon to highlight this). The fact that a deprecation message isn't shown for default cases is an oversight on my part when I implemented the RFC. The merged implementation correctly updated the AST for default case statements followed by a semicolon to support the deprecation message, but I failed to notice that when the compiler code loops over switch cases, there is a `continue` statement when handling the default case which prevents reaching the code for the deprecation. I opened a follow-up pull request to fix this, which can hopefully be merged before PHP 8.5 is released: https://github.com/php/php-src/pull/20172 Kind regards, Theodore > > Smile, > Juliette > > [1]: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_semicolon_after_case_in_switch_statement > [2]: https://github.com/php/php-src/commit/5f8d648af6ef4e29a3c7f2b2029d08466c12bc6f > [3]: https://3v4l.org/liFIK/rfc#vgit.master > [4]: https://externals.io/message/126000

Unnamed Person

321 days ago
On 15-10-2025 6:21, Theodore Brown wrote:
> On Tue, October 14 2025 at 18:08 Juliette Reinders Folmer wrote: > >> Dear Theodore and list, >> >> I've been looking into the "Deprecate semicolon after case in switch statement" PHP 8.5 deprecation [1] >> with the aim of adding a sniff for this to the PHPCompatibility standard and I'm noticing an oddity for >> which I would like to clarify whether this is intentional or an oversight. >> >> As demonstrated in the example code provided in the deprecation RFC, both switch `case` condition >> statements, as well as `default` statements, can be ended with a semicolon. >> >> So when I first read the RFC, I interpreted the proposal to include both `case` as well as `default`, >> as, in my mind, `default` is just a special `case` in a switch. >> >> However, the RFC explicitly only talked about deprecating the use of a semicolon after a >> `case` statement and the implementation has followed this to the letter. [2] >> >> The net result of this, is that you can now have a `switch` statement with semicolons >> terminating `case` statements and `default` statements, where the former (`case`) will >> result in a deprecation notice, while the latter (`default`) will not. For an example, see [3] >> >> This feels inconsistent to me and counter to the intention of the RFC, which is stated to be: >> >>> Case statements followed by a semicolon can cause confusion, as a developer may think they >>> behave differently in some way from regular case statements (e.g. preventing fallthrough), >>> when they do not. >> Which leaves me wondering what the reason was not to _also_ deprecate the use of a semicolon >> to terminate a `default` statement in a switch ? I can't find any discussion about this in the >> original mailing list thread [4]. >> >> Anyone would care to clarify ? > Hi Juliette, > > Thank you for pointing out the discrepancy. You are correct that `default` is just a special > case statement, and the intention in the RFC was to output the deprecation message for default cases > as well (the example in the RFC included a default case followed by a semicolon to highlight this). > > The fact that a deprecation message isn't shown for default cases is an oversight on my part > when I implemented the RFC. The merged implementation correctly updated the AST for default > case statements followed by a semicolon to support the deprecation message, but I failed to > notice that when the compiler code loops over switch cases, there is a `continue` statement > when handling the default case which prevents reaching the code for the deprecation. > > I opened a follow-up pull request to fix this, which can hopefully be merged before > PHP 8.5 is released: https://github.com/php/php-src/pull/20172
Hi Theodore, Ah! That explains it. Bugs happen to the best of us. Glad to hear I didn't misunderstand the intention of the RFC. Thanks for clarifying and for the new PR to update the deprecation implementation. Here's me hoping it will be merged soon. Smile, Juliette