1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Prevent unintersectable template lower bounds

Ref #3264
This commit is contained in:
Brown 2020-04-29 14:57:57 -04:00
parent d3fd9a6acf
commit 891c66650b
4 changed files with 24 additions and 2 deletions

View File

@ -3848,6 +3848,11 @@ class CallAnalyzer
$union_comparison_result = new \Psalm\Internal\Analyzer\TypeComparisonResult();
if (count($template_result->lower_bounds_unintersectable_types) > 1) {
$upper_bound_type = $template_result->lower_bounds_unintersectable_types[0];
$lower_bound_type = $template_result->lower_bounds_unintersectable_types[1];
}
if (!TypeAnalyzer::isContainedBy(
$statements_analyzer->getCodebase(),
$upper_bound_type,

View File

@ -21,6 +21,8 @@ class TemplateResult
*/
public $lower_bounds = [];
public $lower_bounds_unintersectable_types = [];
/**
* @param array<string, array<string, array{0: Union}>> $template_types
* @param array<string, array<string, array{0: Union, 1?: int, 2?: ?int}>> $upper_bounds

View File

@ -616,8 +616,17 @@ class UnionTemplateHandler
$codebase
);
if ($intersection_type) {
$template_result->lower_bounds[$param_name_key][$atomic_type->defining_class][0]
= $intersection_type ?: \Psalm\Type::getMixed();
= $intersection_type;
} else {
$template_result->lower_bounds_unintersectable_types[]
= $template_result->lower_bounds[$param_name_key][$atomic_type->defining_class][0];
$template_result->lower_bounds_unintersectable_types[] = $generic_param;
$template_result->lower_bounds[$param_name_key][$atomic_type->defining_class][0]
= \Psalm\Type::getMixed();
}
} else {
$template_result->lower_bounds[$param_name_key][$atomic_type->defining_class][0]
= $generic_param;

View File

@ -1529,6 +1529,12 @@ class ArrayFunctionCallTest extends TestCase
ints($brr);',
'error_message' => 'ArgumentTypeCoercion - src/somefile.php:5:26 - Argument 1 of ints expects list<int>, parent type array<int, int(2)|int(3)|int(4)|int(5)> provided',
],
'usortOneParamInvalid' => [
'<?php
$list = [3, 2, 5, 9];
usort($list, fn(int $a, string $b): int => (int) ($a > $b));',
'error_message' => 'InvalidScalarArgument'
],
];
}
}