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

Fix #1609 - warn when using covariant template type as input

This commit is contained in:
Brown 2019-05-14 18:17:38 -04:00
parent 6f90e65733
commit 7fbbe964cb
4 changed files with 54 additions and 7 deletions

View File

@ -415,7 +415,9 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer implements Statements
$function_param->type_location,
$storage->suppressed_issues,
[],
false
false,
$this->function instanceof ClassMethod
&& strtolower($this->function->name->name) !== '__construct'
) === false) {
$check_stmts = false;
}

View File

@ -280,7 +280,8 @@ abstract class Atomic
CodeLocation $code_location,
array $suppressed_issues,
array $phantom_classes = [],
$inferred = true
bool $inferred = true,
bool $prevent_template_covariance = false
) {
if ($this->checked) {
return;
@ -359,6 +360,32 @@ abstract class Atomic
}
if ($this instanceof TTemplateParam) {
if ($prevent_template_covariance && $this->defining_class) {
$codebase = $source->getCodebase();
$class_storage = $codebase->classlike_storage_provider->get($this->defining_class);
$template_offset = $class_storage->template_types
? array_search($this->param_name, array_keys($class_storage->template_types))
: false;
if ($template_offset !== false
&& $class_storage->template_covariants
&& $class_storage->template_covariants[$template_offset]
) {
if (IssueBuffer::accepts(
new InvalidTemplateParam(
'Template param ' . $this->defining_class . ' is marked covariant and cannot be used'
. ' as input to a function',
$code_location
),
$source->getSuppressedIssues()
)) {
// fall through
}
}
}
$this->as->check($source, $code_location, $suppressed_issues, $phantom_classes, $inferred);
}
@ -424,7 +451,8 @@ abstract class Atomic
$code_location,
$suppressed_issues,
$phantom_classes,
$inferred
$inferred,
$prevent_template_covariance
);
}
}
@ -436,7 +464,8 @@ abstract class Atomic
$code_location,
$suppressed_issues,
$phantom_classes,
$inferred
$inferred,
$prevent_template_covariance
);
}
}
@ -499,7 +528,8 @@ abstract class Atomic
$code_location,
$suppressed_issues,
$phantom_classes,
$inferred
$inferred,
$prevent_template_covariance
) === false) {
return false;
}

View File

@ -1469,7 +1469,8 @@ class Union
CodeLocation $code_location,
array $suppressed_issues,
array $phantom_classes = [],
$inferred = true
bool $inferred = true,
bool $prevent_template_covariance = false
) {
if ($this->checked) {
return;
@ -1483,7 +1484,8 @@ class Union
$code_location,
$suppressed_issues,
$phantom_classes,
$inferred
$inferred,
$prevent_template_covariance
) === false) {
$all_good = false;
}

View File

@ -2788,6 +2788,19 @@ class TemplateTest extends TestCase
}',
'error_message' => 'InvalidArgument',
],
'preventCovariantParamUsage' => [
'<?php
/**
* @template-covariant T
*/
class Covariant {
/**
* @param T $value
*/
public function set($value): void {}
}',
'error_message' => 'InvalidTemplateParam',
],
];
}
}