1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #1398 - improve casting rules for resource

This commit is contained in:
Matthew Brown 2019-03-01 00:50:22 -05:00
parent 42d4156423
commit d1cf9d61ba
2 changed files with 35 additions and 24 deletions

View File

@ -416,33 +416,35 @@ class ExpressionAnalyzer
return false; return false;
} }
$container_type = Type::getString(); if (isset($stmt->expr->inferredType)) {
foreach ($stmt->expr->inferredType->getTypes() as $atomic_type) {
if (isset($stmt->expr->inferredType) if (!$atomic_type instanceof TMixed
&& !$stmt->expr->inferredType->hasMixed() && !$atomic_type instanceof Type\Atomic\TResource
&& !isset($stmt->expr->inferredType->getTypes()['resource']) && !$atomic_type instanceof TNull
&& !TypeAnalyzer::isContainedBy( && !TypeAnalyzer::isAtomicContainedBy(
$statements_analyzer->getCodebase(), $statements_analyzer->getCodebase(),
$stmt->expr->inferredType, $atomic_type,
$container_type, new TString(),
true, true,
false, false,
$has_scalar_match $has_scalar_match
) )
&& !$has_scalar_match && !$has_scalar_match
) { ) {
if (IssueBuffer::accepts( if (IssueBuffer::accepts(
new InvalidCast( new InvalidCast(
$stmt->expr->inferredType->getId() . ' cannot be cast to ' . $container_type, $atomic_type->getId() . ' cannot be cast to string',
new CodeLocation($statements_analyzer->getSource(), $stmt) new CodeLocation($statements_analyzer->getSource(), $stmt)
), ),
$statements_analyzer->getSuppressedIssues() $statements_analyzer->getSuppressedIssues()
)) { )) {
return false; return false;
}
}
} }
} }
$stmt->inferredType = $container_type; $stmt->inferredType = Type::getString();
} elseif ($stmt instanceof PhpParser\Node\Expr\Cast\Object_) { } elseif ($stmt instanceof PhpParser\Node\Expr\Cast\Object_) {
if (self::analyze($statements_analyzer, $stmt->expr, $context) === false) { if (self::analyze($statements_analyzer, $stmt->expr, $context) === false) {
return false; return false;

View File

@ -186,6 +186,15 @@ class ToStringTest extends TestCase
takesString($a);', takesString($a);',
'error_message' => 'InvalidArgument', 'error_message' => 'InvalidArgument',
], ],
'resourceOrFalseToString' => [
'<?php
$a = fopen("php://memory", "r");
if (rand(0, 1)) {
$a = [];
}
$b = (string) $a;',
'error_message' => 'InvalidCast',
],
]; ];
} }
} }