Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class MutatingScope implements Scope, NodeCallbackInvoker

public const KEEP_VOID_ATTRIBUTE_NAME = 'keepVoid';
private const CONTAINS_SUPER_GLOBAL_ATTRIBUTE_NAME = 'containsSuperGlobal';
private const ARRAY_DIM_FETCH_UNION_MEMBER_LIMIT = 16;

/** @var Type[] */
private array $resolvedTypes = [];
Expand Down Expand Up @@ -2743,10 +2744,12 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType,
}

if ($dimType instanceof ConstantIntegerType || $dimType instanceof ConstantStringType) {
$varType = TypeCombinator::intersect(
$varType,
new HasOffsetValueType($dimType, $type),
);
if (!$this->isLargeUnionType($exprVarType)) {
$varType = TypeCombinator::intersect(
$varType,
new HasOffsetValueType($dimType, $type),
);
}
}

$scope = $scope->specifyExpressionType(
Expand Down Expand Up @@ -2795,6 +2798,15 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType,
return $scope;
}

private function isLargeUnionType(Type $type): bool
{
if (!$type instanceof UnionType) {
return false;
}

return count($type->getTypes()) > self::ARRAY_DIM_FETCH_UNION_MEMBER_LIMIT;
}

public function assignExpression(Expr $expr, Type $type, Type $nativeType): self
{
$scope = $this;
Expand Down
48 changes: 48 additions & 0 deletions tests/bench/data/bug-14462.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php declare(strict_types = 1);

namespace Bug14462;

/** @return array{menu: array<non-empty-string, bool>} */
function get_config(): array {
return ['menu' => []];
}

$config = get_config();

$data = [ ];
if ($config['menu']['notefrais']) {
$data[] = [ 'name' => 'notefrais', 'menu' => 'notefrais_base' ];
}
if ($config['menu']['achat']) {
$data[] = [ 'name' => 'achat', 'menu' => 'achat_base' ];
}

if ($config['menu']['vente-commande_planning'] || $config['menu']['vente-commande']) {
$data[] = [ 'name' => 'vente' , 'menu' => 'vente_order_recent' ];
}
if ($config['menu']['vente-commande_planning']) {
$data[] = [ 'name' => 'vente', 'menu' => 'vente_base_planned' ];
}
if ($config['menu']['vente-commande']) {
$data[] = [ 'name' => 'vente', 'menu' => 'vente_base_com' ];
}
if ($config['menu']['carte']) {
$data[] = [ 'name' => 'carte', 'menu' => '' ];
}
if ($config['menu']['crm']) {
$data[] = [ 'name' => 'crm', 'menu' => 'crm_suivi' ];
}
if ($config['menu']['inventaire']) {
$data[] = [ 'name' => 'inventaire', 'menu' => 'inventaire_base' ];
}


foreach ($data as $row) {
$stack = [ ];
if ($row['menu'] === 'vente_order_recent') {
$stack[] = 'f';
}
else {
$stack[] = 'g';
}
}
Loading