diff --git a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php index 864c3c81087..148d109079a 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -503,7 +503,7 @@ public function analyze( && !$inferred_return_type->isSingleIntLiteral() && !$inferred_return_type->isSingleStringLiteral() && !$inferred_return_type->isTrue() - && $inferred_return_type->getId() !== 'array' + && !$inferred_return_type->isEmptyArray() ) { $manipulator->makePure(); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php index 9f9814669fc..182fdbb387e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php @@ -1024,7 +1024,7 @@ public static function assignByRefParam( $by_ref_out_type->parent_nodes += $existing_type->parent_nodes; } - if ($existing_type->getId() !== 'array') { + if (!$existing_type->isEmptyArray()) { $context->vars_in_scope[$var_id] = $by_ref_out_type; if (!($stmt_type = $statements_analyzer->node_data->getType($stmt)) diff --git a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php index a23020d5116..baf3479524c 100644 --- a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php @@ -554,7 +554,7 @@ private static function reconcileNonEmptyCountable( if (!$array_atomic_type instanceof TNonEmptyArray || ($array_atomic_type->count < $min_count) ) { - if ($array_atomic_type->getId() === 'array') { + if ($array_atomic_type->isEmptyArray()) { $existing_var_type->removeType('array'); } else { $non_empty_array = new TNonEmptyArray( diff --git a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php index 87eb7fc8834..72b5a11488d 100644 --- a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php @@ -486,7 +486,7 @@ private static function reconcileNonEmptyCountable( $did_remove_type = true; $existing_var_type->removeType('array'); - } elseif ($array_atomic_type->getId() !== 'array') { + } elseif (!($array_atomic_type instanceof TArray && $array_atomic_type->isEmptyArray())) { $did_remove_type = true; if (!$min_count) { diff --git a/src/Psalm/Type/Atomic.php b/src/Psalm/Type/Atomic.php index e548df58219..a4c266d2d79 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -785,7 +785,7 @@ public function isFalsy(): bool return true; } - if ($this instanceof TArray && $this->getId() === 'array') { + if ($this instanceof TArray && $this->isEmptyArray()) { return true; } diff --git a/src/Psalm/Type/Union.php b/src/Psalm/Type/Union.php index 843fd742dd7..c0f82a5cec3 100644 --- a/src/Psalm/Type/Union.php +++ b/src/Psalm/Type/Union.php @@ -1598,4 +1598,12 @@ public function getSingleAtomic(): Atomic { return reset($this->types); } + + public function isEmptyArray(): bool + { + return count($this->types) === 1 + && isset($this->types['array']) + && $this->types['array'] instanceof TArray + && $this->types['array']->isEmptyArray(); + } }