Skip to content

Commit 1905131

Browse files
committed
Don't remember types after impure assignments
1 parent ceeb8ab commit 1905131

1 file changed

Lines changed: 38 additions & 32 deletions

File tree

src/Analyser/ExprHandler/AssignHandler.php

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,8 @@ public function processAssignVar(
256256
$falseyType = $falsyScope->getType($assignedExpr->else);
257257

258258
if (
259-
$truthyType->isSuperTypeOf($falseyType)->no()
259+
count($impurePoints) === 0
260+
&& $truthyType->isSuperTypeOf($falseyType)->no()
260261
&& $falseyType->isSuperTypeOf($truthyType)->no()
261262
) {
262263
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
@@ -267,7 +268,10 @@ public function processAssignVar(
267268
}
268269

269270
$truthyType = TypeCombinator::removeFalsey($type);
270-
if ($truthyType !== $type) {
271+
if (
272+
count($impurePoints) === 0
273+
&& $truthyType !== $type
274+
) {
271275
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createTruthy());
272276
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
273277
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
@@ -278,39 +282,41 @@ public function processAssignVar(
278282
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
279283
}
280284

281-
foreach ([null, false, 0, 0.0, '', '0', []] as $falseyScalar) {
282-
$falseyType = ConstantTypeHelper::getTypeFromValue($falseyScalar);
283-
$withoutFalseyType = TypeCombinator::remove($type, $falseyType);
284-
if (
285-
$withoutFalseyType->equals($type)
286-
|| $withoutFalseyType->equals($truthyType)
287-
) {
288-
continue;
289-
}
285+
if (count($impurePoints) === 0) {
286+
foreach ([null, false, 0, 0.0, '', '0', []] as $falseyScalar) {
287+
$falseyType = ConstantTypeHelper::getTypeFromValue($falseyScalar);
288+
$withoutFalseyType = TypeCombinator::remove($type, $falseyType);
289+
if (
290+
$withoutFalseyType->equals($type)
291+
|| $withoutFalseyType->equals($truthyType)
292+
) {
293+
continue;
294+
}
290295

291-
if ($falseyScalar === null) {
292-
$astNode = new ConstFetch(new Name('null'));
293-
} elseif ($falseyScalar === false) {
294-
$astNode = new ConstFetch(new Name('false'));
295-
} elseif ($falseyScalar === 0) {
296-
$astNode = new Node\Scalar\Int_($falseyScalar);
297-
} elseif ($falseyScalar === 0.0) {
298-
$astNode = new Node\Scalar\Float_($falseyScalar);
299-
} elseif (in_array($falseyScalar, ['', '0'], true)) {
300-
$astNode = new Node\Scalar\String_($falseyScalar);
301-
} elseif ($falseyScalar === []) {
302-
$astNode = new Node\Expr\Array_($falseyScalar);
303-
}
296+
if ($falseyScalar === null) {
297+
$astNode = new ConstFetch(new Name('null'));
298+
} elseif ($falseyScalar === false) {
299+
$astNode = new ConstFetch(new Name('false'));
300+
} elseif ($falseyScalar === 0) {
301+
$astNode = new Node\Scalar\Int_($falseyScalar);
302+
} elseif ($falseyScalar === 0.0) {
303+
$astNode = new Node\Scalar\Float_($falseyScalar);
304+
} elseif (in_array($falseyScalar, ['', '0'], true)) {
305+
$astNode = new Node\Scalar\String_($falseyScalar);
306+
} elseif ($falseyScalar === []) {
307+
$astNode = new Node\Expr\Array_($falseyScalar);
308+
}
304309

305-
$notIdenticalConditionExpr = new Expr\BinaryOp\NotIdentical($assignedExpr, $astNode);
306-
$notIdenticalSpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $notIdenticalConditionExpr, TypeSpecifierContext::createTrue());
307-
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $notIdenticalSpecifiedTypes, $withoutFalseyType);
308-
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $notIdenticalSpecifiedTypes, $withoutFalseyType);
310+
$notIdenticalConditionExpr = new Expr\BinaryOp\NotIdentical($assignedExpr, $astNode);
311+
$notIdenticalSpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $notIdenticalConditionExpr, TypeSpecifierContext::createTrue());
312+
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $notIdenticalSpecifiedTypes, $withoutFalseyType);
313+
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $notIdenticalSpecifiedTypes, $withoutFalseyType);
309314

310-
$identicalConditionExpr = new Expr\BinaryOp\Identical($assignedExpr, $astNode);
311-
$identicalSpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $identicalConditionExpr, TypeSpecifierContext::createTrue());
312-
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $identicalSpecifiedTypes, $falseyType);
313-
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $identicalSpecifiedTypes, $falseyType);
315+
$identicalConditionExpr = new Expr\BinaryOp\Identical($assignedExpr, $astNode);
316+
$identicalSpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $identicalConditionExpr, TypeSpecifierContext::createTrue());
317+
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $identicalSpecifiedTypes, $falseyType);
318+
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $identicalSpecifiedTypes, $falseyType);
319+
}
314320
}
315321

316322
$nodeScopeResolver->callNodeCallback($nodeCallback, new VariableAssignNode($var, $assignedExpr), $scopeBeforeAssignEval, $storage);

0 commit comments

Comments
 (0)