Skip to content

Incorrect behavior of LogicalToBooleanRector: removing important parentheses in some cases #9799

Description

@glop-glop

Bug Report

Subject Details
Rector version last dev-main (rectorphp/rector-src@269af160)

Hello,

This is a follow-up on #9797 and rectorphp/rector-src#8151: the patch in rectorphp/rector-src#8151 correctly fixed the reported bug, but I found out there is still a parenthesizing issue with the LogicalToBooleanRector rule.

Minimal PHP Code Causing Issue

I cannot provide a working example on https://getrector.com/demo/ as the fix from rectorphp/rector-src#8151 is not deployed there yet. However, the following code should demonstrate the issue:

<?php

true and ($x = 42) and false;

var_dump($x);

(Note the parentheses around the assignment $x = 42. They are not strictly necessary, but may have been written to improve code readability.)

Responsible rule: LogicalToBooleanRector

The current main branch of Rector will rewrite the 3rd line in the above example as

true && $x = 42 && false;

That is, it will replace the and's by &&'s, as expected, but will also remove the parentheses around $x = 42. And if these parentheses were optional with logical operators (and), they are necessary when using boolean ones (&&), and the rewritten code is now incorrectly equivalent to

true && $x = (42 && false);

Expected Behaviour

A valid rewrite would be the following:

true && ($x = 42) && false;

That is, keep the parentheses around the assignment.

I'm not really sure how the patch from rectorphp/rector-src#8151 works, but I'm under the impression that it will add parentheses around the assignment node only if there wasn't any parentheses in the original code (if I understand line 483 of src/PhpParser/Printer/BetterStandardPrinter.php correctly). Therefore, if I'm not mistaken, it will correctly add parentheses if they're missing (which fixes #9797), but will incorrectly remove them if they were already present (hence this issue).

Thank you very much!

Cheers,
Glop

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions