1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Merge pull request #9606 from orklah/edfghjhkjl

fix coercion detection between two keyed arrays
This commit is contained in:
orklah 2023-04-04 12:59:55 +02:00 committed by GitHub
commit bf0740a58c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 20 deletions

View File

@ -84,24 +84,47 @@ class KeyedArrayComparator
$property_type_comparison,
$allow_interface_equality,
);
if (!$is_input_containedby_container && !$property_type_comparison->type_coerced_from_scalar) {
$inverse_property_type_comparison = new TypeComparisonResult();
if (!$is_input_containedby_container) {
if ($atomic_comparison_result) {
if (UnionTypeComparator::isContainedBy(
$codebase,
$container_property_type,
$input_property_type,
false,
false,
$inverse_property_type_comparison,
$allow_interface_equality,
)
|| $inverse_property_type_comparison->type_coerced_from_scalar
) {
$atomic_comparison_result->type_coerced = true;
$atomic_comparison_result->type_coerced
= $property_type_comparison->type_coerced === true
&& $atomic_comparison_result->type_coerced !== false;
if (!$property_type_comparison->type_coerced_from_scalar
&& !$atomic_comparison_result->type_coerced) {
//if we didn't detect a coercion, we try to compare the other way around
$inverse_property_type_comparison = new TypeComparisonResult();
if (UnionTypeComparator::isContainedBy(
$codebase,
$container_property_type,
$input_property_type,
false,
false,
$inverse_property_type_comparison,
$allow_interface_equality,
)
|| $inverse_property_type_comparison->type_coerced_from_scalar
) {
$atomic_comparison_result->type_coerced = true;
}
}
$atomic_comparison_result->type_coerced_from_mixed
= $property_type_comparison->type_coerced_from_mixed === true
&& $atomic_comparison_result->type_coerced_from_mixed !== false;
$atomic_comparison_result->type_coerced_from_as_mixed
= $property_type_comparison->type_coerced_from_as_mixed === true
&& $atomic_comparison_result->type_coerced_from_as_mixed !== false;
$atomic_comparison_result->type_coerced_from_scalar
= $property_type_comparison->type_coerced_from_scalar === true
&& $atomic_comparison_result->type_coerced_from_scalar !== false;
$atomic_comparison_result->scalar_type_match_found
= $property_type_comparison->scalar_type_match_found === true
&& $atomic_comparison_result->scalar_type_match_found !== false;
if ($property_type_comparison->missing_shape_fields) {
$atomic_comparison_result->missing_shape_fields
= $property_type_comparison->missing_shape_fields;
@ -110,9 +133,6 @@ class KeyedArrayComparator
$all_types_contain = false;
} else {
if (!$is_input_containedby_container) {
$all_types_contain = false;
}
if ($atomic_comparison_result) {
$atomic_comparison_result->to_string_cast
= $atomic_comparison_result->to_string_cast === true

View File

@ -2691,7 +2691,7 @@ class FunctionCallTest extends TestCase
takesArrayShapeWithZeroOrPositiveInt(["bar" => $mayBeInt]);
',
'error_message' => 'InvalidArgument',
'error_message' => 'ArgumentTypeCoercion',
],
'is_a_withAStringAndNoThirdArg' => [
'code' => '<?php

View File

@ -1243,6 +1243,27 @@ class ReturnTypeTest extends TestCase
}
',
],
'MixedErrorInArrayShouldBeReportedAsMixedError' => [
'code' => '<?php
/**
* @param mixed $configuration
* @return array{a?: string, b?: int}
* @psalm-suppress MixedReturnTypeCoercion
*/
function produceParameters(array $configuration): array
{
$parameters = [];
foreach (["a", "b"] as $parameter) {
/** @psalm-suppress MixedAssignment */
$parameters[$parameter] = $configuration;
}
/** @psalm-suppress MixedReturnTypeCoercion */
return $parameters;
}
',
],
];
}

View File

@ -4681,7 +4681,7 @@ class ClassTemplateTest extends TestCase
$m = new Map(fn(int $num) => (string) $num);
$m(["a"]);',
'error_message' => 'InvalidArgument',
'error_message' => 'InvalidScalarArgument',
'ignored_issues' => [],
'php_version' => '8.0',
],