Skip to content

[CodeQuality] Fix AddInstanceofAssertForNullableArgumentRector duplicate assertInstanceOf inside traits - #773

Merged
TomasVotruba merged 1 commit into
mainfrom
fix-instanceof-assert-trait-idempotency
Aug 25, 2026
Merged

[CodeQuality] Fix AddInstanceofAssertForNullableArgumentRector duplicate assertInstanceOf inside traits#773
TomasVotruba merged 1 commit into
mainfrom
fix-instanceof-assert-trait-idempotency

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Fixesrectorphp/rector#9863

Problem

Inside a test trait, AddInstanceofAssertForNullableArgumentRector is not idempotent. Every rector process run appends one more identical $this->assertInstanceOf(...) line, forever.

The rule's only cross-run guard was implicit: the inserted $this->assertInstanceOf() narrows the variable's type, so SimpleTypeAnalyzer::isNullableType() stops matching on the next run. In a class extending TestCase that holds. In a trait $this is not a PHPUnit\Framework\Assert, so the assert never narrows, the variable stays nullable, and a fresh assert is appended each run.

 $someObject = $someFactory->create();
$this->assertInstanceOf(SomeClass::class, $someObject);
+$this->assertInstanceOf(SomeClass::class, $someObject); // added again every run
$someFactory->process($someObject);

Fix

Stop depending on type narrowing for idempotency. While scanning statements, detect a pre-existing assertInstanceOf(<Type>::class, $variable) and drop that variable from the nullable collection, so no second assert is spliced in. Works in both classes and traits, and hardens the class case when the PHPUnit type-specifying extension is unavailable.

Tests

  • skip_already_asserted_in_trait.php.inc — trait already carrying the assert stays unchanged (fails before the fix: a duplicate assert is added).
  • nullable_arg_in_trait.php.inc — the rule still fires once in a trait.

…ate assertInstanceOf on every run inside traits
@TomasVotruba
TomasVotruba merged commit e2d2cfb into mainAug 25, 2026
11 of 13 checks passed
@TomasVotruba

Copy link
Copy Markdown
MemberAuthor

Let's ship it 👍

@TomasVotruba
TomasVotruba deleted the fix-instanceof-assert-trait-idempotency branch August 25, 2026 15:57
Sign up for freeto 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.

[PHPUnit] AddInstanceofAssertForNullableArgumentRector adds a duplicate assertInstanceOf on every run inside traits

1 participant

@TomasVotruba