Skip to content
Merged
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
12 changes: 8 additions & 4 deletions src/Analyser/ExprHandler/ScalarHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ public function supports(Expr $expr): bool

public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Expr $expr, MutatingScope $scope, ExpressionResultStorage $storage, callable $nodeCallback, ExpressionContext $context): ExpressionResult
{
// a literal's type and its initializer context (file/namespace/class) are
// lexical - identical on every scope - so build the context once here.
$initializerExprContext = InitializerExprContext::fromScope($scope);
// a literal's type is lexical - identical on every scope and in both
// flavours - and cheaper to hold than a lazy typeCallback capturing the
// initializer context, which matters in large array literals whose item
// results all stay alive until the array's own type is resolved
$type = $this->initializerExprTypeResolver->getType($expr, InitializerExprContext::fromScope($scope));

return $this->expressionResultFactory->create(
$scope,
Expand All @@ -53,8 +55,10 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
isAlwaysTerminating: false,
throwPoints: [],
impurePoints: [],
typeCallback: fn () => $this->initializerExprTypeResolver->getType($expr, $initializerExprContext),
typeCallback: null,
specifyTypesCallback: SpecifiedTypes::emptySpecifyCallback(),
type: $type,
nativeType: $type,
);
}

Expand Down
16 changes: 13 additions & 3 deletions src/Rules/Arrays/DuplicateKeysInLiteralArraysRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use function array_search;
use function array_values;
use function count;
use function get_debug_type;
use function implode;
use function is_bool;
use function is_float;
Expand Down Expand Up @@ -153,7 +154,7 @@ public function processNode(Node $node, Scope $scope): array
$duplicate = false;
$newValues = $keyValues;
foreach ($newValues as $k => $newValue) {
if (array_search($newValue, $seenKeys, true) !== false) {
if (isset($seenKeys[self::getSeenKey($newValue)])) {
unset($newValues[$k]);
}

Expand All @@ -179,10 +180,10 @@ public function processNode(Node $node, Scope $scope): array
continue;
}

$seenKeys[] = $seenUnions[$k][array_key_first($seenUnions[$k])];
$seenKeys[self::getSeenKey($seenUnions[$k][array_key_first($seenUnions[$k])])] = true;
unset($seenUnions[$k]);
}
$seenKeys[] = $newValue;
$seenKeys[self::getSeenKey($newValue)] = true;
} else {
$seenUnions[] = $newValues;
}
Expand Down Expand Up @@ -228,4 +229,13 @@ public function processNode(Node $node, Scope $scope): array
return $messages;
}

/**
* Indexes seen key values by their type and value, so that looking one up
* is as strict as an identity comparison without scanning every key seen so far.
*/
private static function getSeenKey(int|float|string|bool|null $value): string
{
return get_debug_type($value) . ':' . var_export($value, true);
}

}
2 changes: 1 addition & 1 deletion src/Turbo/TurboExtensionEnabler.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
final class TurboExtensionEnabler
{

public const EXPECTED_EXTENSION_VERSION = 'fbf40c7';
public const EXPECTED_EXTENSION_VERSION = '09aa561';

private static bool $active = false;

Expand Down
Loading
Loading