Skip to content

fix: preserve ternary fallback parentheses in new coalesces - #8927

Open
smotim wants to merge 1 commit into
rectorphp:mainfrom
smotim:fix/coalesce-ternary-parentheses
Open

smotim wants to merge 1 commit into
rectorphp:mainfrom
smotim:fix/coalesce-ternary-parentheses

Conversation

@smotim

@smotim smotim commented Nov 8, 2026 •

Copy link
Copy Markdown

TernaryToNullsafeCoalesceRector can change the behavior of an expression when its fallback is another ternary:

// Before transformation:
return $object !== null ? $object->name : ($flag ? 'first' : 'second');

// Actual output before this fix:
return $object->name ?? $flag ? 'first' : 'second';

// Expected output:
return $object->name ?? ($flag ? 'first' : 'second');

When the object exists and its name is 'name', the original expression returns 'name', while the incorrect output returns 'first'. During format-preserving printing of a new Coalesce, the reused ternary operand loses its original parentheses.

Mark the right-hand ternary operand of a new Coalesce with the existing WRAPPED_IN_PARENTHESES attribute. This preserves the original nodes and formatting, including rules that already set this attribute themselves.

Add a regression fixture covering property access, a nullsafe method call, and a reversed comparison with null with a short ternary fallback. The fixture fails on the original main branch and passes with this change.

Validation on PHP 8.4: composer check-cs, composer phpstan, and the full vendor/bin/phpunit suite pass: 4,903 tests, 5,928 assertions, and one existing skipped test. All 26 focused rule and printer tests also pass.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant