Skip to content
Permalink
Browse files

Fix #1842 - prevent bad templated object returns

  • Loading branch information...
muglug committed Jun 24, 2019
1 parent 44d52c8 commit 23a3b0dbc008bd83cf38bfd5937ce8396892045e
@@ -735,7 +735,9 @@ public static function isAtomicContainedBy(
$to_string_cast,
$type_coerced_from_scalar
)) {
return true;
if ($allow_interface_equality || !$input_type_part instanceof TNamedObject) {
return true;
}
}
}
@@ -1009,6 +1009,12 @@ public function replaceTemplateTypesWithStandins(
= clone $key_type;
}
}
if ($replacement_atomic_type instanceof Type\Atomic\TTemplateParam) {
foreach ($replacement_atomic_type->as->getTypes() as $nested_type_atomic) {
$this->types[$nested_type_atomic->getKey()] = clone $nested_type_atomic;
}
}
// @codingStandardsIgnoreEnd
if (!$replacements_found) {
@@ -776,6 +776,50 @@ private function iterate() : void {
}
}',
],
'extendWithExplicitOverriddenTemplatedSignature' => [
'<?php
class Obj {}
/**
* @template T1
*/
class BaseContainer {
/** @var T1 */
private $t1;
/** @param T1 $t1 */
public function __construct($t1) {
$this->t1 = $t1;
}
/**
* @return T1
*/
public function getValue()
{
return $this->t1;
}
}
/**
* @template T2 as Obj
* @template-extends BaseContainer<T2>
*/
class Container extends BaseContainer {
/** @param T2 $t2 */
public function __construct($t2) {
parent::__construct($t2);
}
/**
* @return T2
*/
public function getValue()
{
return parent::getValue();
}
}',
],
'iterateOverExtendedArrayObjectThisClassIterationWithExplicitGetIterator' => [
'<?php
class O {}
@@ -805,9 +849,7 @@ public function __construct(string $class) {
/**
* @return \ArrayIterator<int, T>
*/
public function getIterator()
{
/** @var ArrayIterator<int, O> */
public function getIterator() {
return parent::getIterator();
}
}
@@ -1117,6 +1159,50 @@ public function bar() : void {
}
}',
],
'templateExtendsOnceWithSpecificStaticCall' => [
'<?php
/** @template T */
class Container {
/** @var T */
private $t;
/** @param T $t */
private function __construct($t) {
$this->t = $t;
}
/**
* @param T $t
* @return static<T>
*/
public static function getContainer($t) {
return new static($t);
}
/**
* @return T
*/
public function getValue()
{
return $this->t;
}
}
/**
* @template T1 as A
* @template-extends Container<T1>
*/
class AContainer extends Container {}
class A {
function foo() : void {}
}
$b = AContainer::getContainer(new A());',
[
'$b' => 'AContainer<A>',
],
],
'templateExtendsDifferentNameWithStaticCall' => [
'<?php
/** @template T */
@@ -1012,7 +1012,6 @@ class I {
/**
* @template T as Foo
* @param class-string<T> $class
* @template-typeof T $class
* @return T|null
*/
public function loader(string $class) {
@@ -3446,6 +3445,17 @@ public function getObject(string $type)
}',
'error_message' => 'InvalidReturnStatement'
],
'preventTemplateTypeAsBeingUsedInsideFunction' => [
'<?php
/**
* @template T of DateTime
* @param callable(T) $callable
*/
function foo(callable $callable) : void {
$callable(new \DateTime());
}',
'error_message' => 'InvalidArgument'
],
'preventWrongTemplateBeingPassed' => [
'<?php
/**
@@ -3461,6 +3471,19 @@ function foo(callable $parameter, $value)
}',
'error_message' => 'InvalidArgument'
],
'preventTemplateTypeReturnMoreGeneral' => [
'<?php
/**
* @template T of DateTimeInterface
* @param T $x
* @return T
*/
function foo($x)
{
return new \DateTime();
}',
'error_message' => 'InvalidReturnStatement'
],
];
}
}

0 comments on commit 23a3b0d

Please sign in to comment.
You can’t perform that action at this time.