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

Fix #2384 - fix resolution of @param-out template types

This commit is contained in:
Matthew Brown 2019-12-01 10:40:53 -05:00
parent ef829002bf
commit f21150b8ad
2 changed files with 44 additions and 3 deletions

View File

@ -1621,10 +1621,8 @@ class CallAnalyzer
if ($template_result && $by_ref_type) { if ($template_result && $by_ref_type) {
$original_by_ref_type = clone $by_ref_type; $original_by_ref_type = clone $by_ref_type;
$by_ref_type = clone $by_ref_type;
$by_ref_type = UnionTemplateHandler::replaceTemplateTypesWithStandins( $by_ref_type = UnionTemplateHandler::replaceTemplateTypesWithStandins(
$by_ref_type, clone $by_ref_type,
$template_result, $template_result,
$codebase, $codebase,
$statements_analyzer->node_data->getType($arg->value), $statements_analyzer->node_data->getType($arg->value),
@ -1640,6 +1638,26 @@ class CallAnalyzer
} }
} }
if ($template_result && $by_ref_out_type) {
$original_by_ref_out_type = clone $by_ref_type;
$by_ref_out_type = UnionTemplateHandler::replaceTemplateTypesWithStandins(
clone $by_ref_out_type,
$template_result,
$codebase,
$statements_analyzer->node_data->getType($arg->value),
null
);
if ($template_result->generic_params) {
$original_by_ref_out_type->replaceTemplateTypesWithArgTypes(
$template_result->generic_params
);
$by_ref_out_type = $original_by_ref_out_type;
}
}
if ($by_ref_type && $function_param->is_variadic && $arg->unpack) { if ($by_ref_type && $function_param->is_variadic && $arg->unpack) {
$by_ref_type = new Type\Union([ $by_ref_type = new Type\Union([
new Type\Atomic\TArray([ new Type\Atomic\TArray([

View File

@ -819,6 +819,29 @@ class FunctionTemplateTest extends TestCase
echo collect("a");' echo collect("a");'
], ],
'paramOutDontLeak' => [
'<?php
/**
* @template TKey as array-key
* @template TValue
*
* @param array<TKey, TValue> $arr
* @param-out list<TValue> $arr
*/
function example_sort_by_ref(array &$arr): bool {
$arr = array_values($arr);
return true;
}
/**
* @param array<int, array{0: int, 1: string}> $array
* @return array<int, array{0: int, 1: string}>
*/
function example(array $array): array {
example_sort_by_ref($array);
return $array;
}',
],
]; ];
} }