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:
parent
6f90e65733
commit
7fbbe964cb
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user