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

Fix #5799 — improve expansion of templated types

This commit is contained in:
Matt Brown 2021-05-23 14:39:54 -04:00
parent 89f815ff62
commit d1262b0bec
2 changed files with 37 additions and 6 deletions

View File

@ -117,7 +117,7 @@ class TemplateInferredTypeReplacer
$is_mixed = true;
}
$new_types[$template_type_part->getKey()] = $template_type_part;
$new_types[] = $template_type_part;
}
}
} elseif ($atomic_type instanceof Atomic\TTemplateParamClass) {
@ -153,7 +153,7 @@ class TemplateInferredTypeReplacer
if ($class_template_type) {
$keys_to_unset[] = $key;
$new_types[$class_template_type->getKey()] = $class_template_type;
$new_types[] = $class_template_type;
}
} elseif ($atomic_type instanceof Atomic\TTemplateIndexedAccess) {
$keys_to_unset[] = $key;
@ -194,10 +194,10 @@ class TemplateInferredTypeReplacer
$is_mixed = true;
}
$new_types[$template_type_part->getKey()] = $template_type_part;
$new_types[] = $template_type_part;
}
} else {
$new_types[$key] = new Atomic\TMixed();
$new_types[] = new Atomic\TMixed();
}
} elseif ($atomic_type instanceof Atomic\TConditional
&& $codebase
@ -347,7 +347,7 @@ class TemplateInferredTypeReplacer
$keys_to_unset[] = $key;
foreach ($class_template_type->getAtomicTypes() as $class_template_atomic_type) {
$new_types[$class_template_atomic_type->getKey()] = $class_template_atomic_type;
$new_types[] = $class_template_atomic_type;
}
}
}
@ -359,7 +359,12 @@ class TemplateInferredTypeReplacer
throw new \UnexpectedValueException('This array should be full');
}
$union->replaceTypes($new_types);
$union->replaceTypes(
TypeCombiner::combine(
$new_types,
$codebase
)->getAtomicTypes()
);
return;
}

View File

@ -3371,6 +3371,32 @@ class ClassTemplateTest extends TestCase
}
',
],
'combineTwoTemplatedArrays' => [
'<?php
/** @template T */
class Option
{
/** @param T $v */
public function __construct(private $v) {}
/**
* @template E
* @param E $else
* @return T|E
*/
public function getOrElse($else)
{
return rand(0, 1) === 1 ? $this->v : $else;
}
}
$opt = new Option([1, 3]);
$b = $opt->getOrElse([2, 4])[0];',
[
'$b===' => '1|2'
]
],
];
}