Skip to content

Commit b43c057

Browse files
committed
Fix unset() on intersection with hasOffset
1 parent 8fc2f23 commit b43c057

28 files changed

+177
-129
lines changed

src/Analyser/MutatingScope.php

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3694,27 +3694,12 @@ public function unsetExpression(Expr $expr): self
36943694
$this->parentScope,
36953695
);
36963696
} elseif ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) {
3697-
$varType = $this->getType($expr->var);
3698-
$constantArrays = TypeUtils::getConstantArrays($varType);
3699-
if (count($constantArrays) > 0) {
3700-
$unsetArrays = [];
3701-
$dimType = $this->getType($expr->dim);
3702-
foreach ($constantArrays as $constantArray) {
3703-
$unsetArrays[] = $constantArray->unsetOffset($dimType);
3704-
}
3705-
return $this->specifyExpressionType(
3706-
$expr->var,
3707-
TypeCombinator::union(...$unsetArrays),
3708-
);
3709-
}
3710-
3711-
$arrays = TypeUtils::getArrays($varType);
3712-
$scope = $this;
3713-
if (count($arrays) > 0) {
3714-
$scope = $scope->specifyExpressionType($expr->var, TypeCombinator::union(...$arrays));
3715-
}
3716-
3717-
return $scope->invalidateExpression($expr->var);
3697+
return $this->specifyExpressionType(
3698+
$expr->var,
3699+
$this->getType($expr->var)->unsetOffset($this->getType($expr->dim)),
3700+
)->invalidateExpression(
3701+
new FuncCall(new FullyQualified('count'), [new Arg($expr->var)]),
3702+
);
37183703
}
37193704

37203705
return $this;

src/Type/Accessory/AccessoryLiteralStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
115115
return $this;
116116
}
117117

118+
public function unsetOffset(Type $offsetType): Type
119+
{
120+
return new ErrorType();
121+
}
122+
118123
public function isArray(): TrinaryLogic
119124
{
120125
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryNonEmptyStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
116116
return $this;
117117
}
118118

119+
public function unsetOffset(Type $offsetType): Type
120+
{
121+
return new ErrorType();
122+
}
123+
119124
public function isArray(): TrinaryLogic
120125
{
121126
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryNumericStringType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
112112
return $this;
113113
}
114114

115+
public function unsetOffset(Type $offsetType): Type
116+
{
117+
return new ErrorType();
118+
}
119+
115120
public function isArray(): TrinaryLogic
116121
{
117122
return TrinaryLogic::createNo();

src/Type/Accessory/HasOffsetType.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
114114
return $this;
115115
}
116116

117+
public function unsetOffset(Type $offsetType): Type
118+
{
119+
if ($this->offsetType->isSuperTypeOf($offsetType)->yes()) {
120+
return new ErrorType();
121+
}
122+
return $this;
123+
}
124+
117125
public function isIterableAtLeastOnce(): TrinaryLogic
118126
{
119127
return TrinaryLogic::createYes();

src/Type/Accessory/NonEmptyArrayType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
107107
return $this;
108108
}
109109

110+
public function unsetOffset(Type $offsetType): Type
111+
{
112+
return new ErrorType();
113+
}
114+
110115
public function isIterable(): TrinaryLogic
111116
{
112117
return TrinaryLogic::createYes();

src/Type/ArrayType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
255255
), new NonEmptyArrayType());
256256
}
257257

258+
public function unsetOffset(Type $offsetType): Type
259+
{
260+
return $this;
261+
}
262+
258263
public function isCallable(): TrinaryLogic
259264
{
260265
return TrinaryLogic::createMaybe()->and((new StringType())->isSuperTypeOf($this->itemType));

src/Type/BooleanType.php

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace PHPStan\Type;
44

5-
use PHPStan\TrinaryLogic;
65
use PHPStan\Type\Constant\ConstantArrayType;
76
use PHPStan\Type\Constant\ConstantFloatType;
87
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -11,6 +10,7 @@
1110
use PHPStan\Type\Traits\NonGenericTypeTrait;
1211
use PHPStan\Type\Traits\NonIterableTypeTrait;
1312
use PHPStan\Type\Traits\NonObjectTypeTrait;
13+
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
1414
use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
1515
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
1616

@@ -25,6 +25,7 @@ class BooleanType implements Type
2525
use UndecidedBooleanTypeTrait;
2626
use UndecidedComparisonTypeTrait;
2727
use NonGenericTypeTrait;
28+
use NonOffsetAccessibleTypeTrait;
2829

2930
/** @api */
3031
public function __construct()
@@ -74,26 +75,6 @@ public function toArray(): Type
7475
);
7576
}
7677

77-
public function isOffsetAccessible(): TrinaryLogic
78-
{
79-
return TrinaryLogic::createNo();
80-
}
81-
82-
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
83-
{
84-
return TrinaryLogic::createNo();
85-
}
86-
87-
public function getOffsetValueType(Type $offsetType): Type
88-
{
89-
return new ErrorType();
90-
}
91-
92-
public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
93-
{
94-
return new ErrorType();
95-
}
96-
9778
/**
9879
* @param mixed[] $properties
9980
*/

src/Type/ClosureType.php

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use PHPStan\Type\Generic\TemplateTypeHelper;
2424
use PHPStan\Type\Generic\TemplateTypeMap;
2525
use PHPStan\Type\Traits\NonGenericTypeTrait;
26+
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
2627
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
2728
use function array_map;
2829
use function array_merge;
@@ -35,6 +36,7 @@ class ClosureType implements TypeWithClassName, ParametersAcceptor
3536

3637
use NonGenericTypeTrait;
3738
use UndecidedComparisonTypeTrait;
39+
use NonOffsetAccessibleTypeTrait;
3840

3941
private ObjectType $objectType;
4042

@@ -228,26 +230,6 @@ public function getIterableValueType(): Type
228230
return new ErrorType();
229231
}
230232

231-
public function isOffsetAccessible(): TrinaryLogic
232-
{
233-
return TrinaryLogic::createNo();
234-
}
235-
236-
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
237-
{
238-
return TrinaryLogic::createNo();
239-
}
240-
241-
public function getOffsetValueType(Type $offsetType): Type
242-
{
243-
return new ErrorType();
244-
}
245-
246-
public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
247-
{
248-
return new ErrorType();
249-
}
250-
251233
public function isCallable(): TrinaryLogic
252234
{
253235
return TrinaryLogic::createYes();

src/Type/FloatType.php

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\Type\Traits\NonGenericTypeTrait;
1111
use PHPStan\Type\Traits\NonIterableTypeTrait;
1212
use PHPStan\Type\Traits\NonObjectTypeTrait;
13+
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
1314
use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
1415
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
1516
use function get_class;
@@ -24,6 +25,7 @@ class FloatType implements Type
2425
use UndecidedBooleanTypeTrait;
2526
use UndecidedComparisonTypeTrait;
2627
use NonGenericTypeTrait;
28+
use NonOffsetAccessibleTypeTrait;
2729

2830
/** @api */
2931
public function __construct()
@@ -109,26 +111,6 @@ public function toArray(): Type
109111
);
110112
}
111113

112-
public function isOffsetAccessible(): TrinaryLogic
113-
{
114-
return TrinaryLogic::createNo();
115-
}
116-
117-
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
118-
{
119-
return TrinaryLogic::createNo();
120-
}
121-
122-
public function getOffsetValueType(Type $offsetType): Type
123-
{
124-
return new ErrorType();
125-
}
126-
127-
public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
128-
{
129-
return new ErrorType();
130-
}
131-
132114
public function isArray(): TrinaryLogic
133115
{
134116
return TrinaryLogic::createNo();

0 commit comments

Comments
 (0)