1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #741 - make sure closures are cloned properly

This commit is contained in:
Matt Brown 2018-05-18 17:47:40 -04:00
parent b0733254bb
commit c6aa396dea
3 changed files with 52 additions and 1 deletions

View File

@ -31,6 +31,17 @@ trait CallableTrait
$this->return_type = $return_type;
}
public function __clone()
{
if ($this->params) {
foreach ($this->params as &$param) {
$param = clone $param;
}
}
$this->return_type = $this->return_type ? clone $this->return_type : null;
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes

View File

@ -783,7 +783,7 @@ class Union
foreach ($this->types as $key => $atomic_type) {
if (isset($template_types[$key])) {
$keys_to_unset[] = $key;
$template_type = $template_types[$key];
$template_type = clone $template_types[$key];
foreach ($template_type->types as $template_type_part) {
if ($template_type_part instanceof Type\Atomic\TMixed) {

View File

@ -534,6 +534,46 @@ class TemplateTest extends TestCase
takesInt(retry(1, function(): int { return 1; }));',
],
'repeatedCall' => [
'<?php
namespace NS;
use Closure;
/**
* @template TKey
* @template TValue
*/
class ArrayCollection {
/** @var array<TKey,TValue> */
private $data;
/** @param array<TKey,TValue> $data */
public function __construct(array $data) {
$this->data = $data;
}
/**
* @template T
* @param Closure(TValue):T $func
* @return ArrayCollection<TKey,T>
*/
public function map(Closure $func) {
return new static(array_map($func, $this->data));
}
}
class Item {}
/**
* @param ArrayCollection<mixed,Item> $i
*/
function takesCollectionOfItems(ArrayCollection $i): void {}
$c = new ArrayCollection([ new Item ]);
takesCollectionOfItems($c);
takesCollectionOfItems($c->map(function(Item $i): Item { return $i;}));
takesCollectionOfItems($c->map(function(Item $i): Item { return $i;}));'
],
];
}