From e4212976d63e32cf6558930aa8e10376a37907d8 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 4 Aug 2026 14:38:50 +0700 Subject: [PATCH 1/2] [DeadCode] Skip assert() enforcement that produce NeverType on NarrowWideUnionReturnTypeRector --- .../FunctionLike/NarrowWideUnionReturnTypeRector.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rules/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector.php b/rules/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector.php index 99ffb859742..2f0d6948e9f 100644 --- a/rules/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector.php +++ b/rules/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector.php @@ -20,6 +20,7 @@ use PhpParser\Node\UnionType; use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; use PHPStan\Reflection\ClassReflection; +use PHPStan\Type\NeverType; use PHPStan\Type\NullType; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; @@ -272,6 +273,13 @@ private function collectActualReturnTypes(array $returnStatements): array private function resolveNativeReturnTypes(Expr $expr): array { if (! $expr instanceof Ternary || ! $this->hasVendorClassConstFetch($expr->cond)) { + $type = $this->nodeTypeResolver->getType($expr); + + // native type may be narrowed by assertions even when the resolved scope is unreachable + if ($type instanceof NeverType) { + return [$type]; + } + return [$this->nodeTypeResolver->getNativeType($expr)]; } From 2c22b1925b360660ae2550d7945f2e812dbeb637 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 4 Aug 2026 14:38:54 +0700 Subject: [PATCH 2/2] [DeadCode] Skip assert() enforcement that produce NeverType on NarrowWideUnionReturnTypeRector --- .../Fixture/skip_assert.php.inc | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 rules-tests/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector/Fixture/skip_assert.php.inc diff --git a/rules-tests/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector/Fixture/skip_assert.php.inc b/rules-tests/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector/Fixture/skip_assert.php.inc new file mode 100644 index 00000000000..afbd13a8d60 --- /dev/null +++ b/rules-tests/DeadCode/Rector/FunctionLike/NarrowWideUnionReturnTypeRector/Fixture/skip_assert.php.inc @@ -0,0 +1,26 @@ + [ + 'directory' => null, + ], + ]; + + public function getCacheDirectory(): ?string + { + $dir = $this->config['cache']['directory'] ?? null; + \assert(\is_string($dir) || $dir === null, 'Invalid cache directory.'); + + return $dir; + } +} +