diff --git a/src/Psalm/Checker/Statements/Expression/Assignment/PropertyAssignmentChecker.php b/src/Psalm/Checker/Statements/Expression/Assignment/PropertyAssignmentChecker.php index ea974935e..49a43e6c8 100644 --- a/src/Psalm/Checker/Statements/Expression/Assignment/PropertyAssignmentChecker.php +++ b/src/Psalm/Checker/Statements/Expression/Assignment/PropertyAssignmentChecker.php @@ -15,6 +15,7 @@ use Psalm\Issue\ImplicitToStringCast; use Psalm\Issue\InvalidPropertyAssignment; use Psalm\Issue\InvalidPropertyAssignmentValue; use Psalm\Issue\LoopInvalidation; +use Psalm\Issue\MixedAssignment; use Psalm\Issue\MixedPropertyAssignment; use Psalm\Issue\MixedTypeCoercion; use Psalm\Issue\NoInterfaceProperties; @@ -381,6 +382,18 @@ class PropertyAssignmentChecker $lhs_type_part->value, $lhs_type_part->value ); + + if (!$class_property_type->isMixed() && $assignment_value_type->isMixed()) { + if (IssueBuffer::accepts( + new MixedAssignment( + 'Cannot assign ' . $var_id . ' to a mixed type', + new CodeLocation($statements_checker->getSource(), $stmt) + ), + $statements_checker->getSuppressedIssues() + )) { + // fall through + } + } } $class_property_types[] = $class_property_type; diff --git a/src/Psalm/Checker/Statements/Expression/AssignmentChecker.php b/src/Psalm/Checker/Statements/Expression/AssignmentChecker.php index 66dd033f2..273641c3e 100644 --- a/src/Psalm/Checker/Statements/Expression/AssignmentChecker.php +++ b/src/Psalm/Checker/Statements/Expression/AssignmentChecker.php @@ -172,14 +172,16 @@ class AssignmentChecker if ($assign_value_type->isMixed()) { $codebase->analyzer->incrementMixedCount($statements_checker->getCheckedFilePath()); - if (IssueBuffer::accepts( - new MixedAssignment( - 'Cannot assign ' . $var_id . ' to a mixed type', - new CodeLocation($statements_checker->getSource(), $assign_var) - ), - $statements_checker->getSuppressedIssues() - )) { - // fall through + if (!$assign_var instanceof PhpParser\Node\Expr\PropertyFetch) { + if (IssueBuffer::accepts( + new MixedAssignment( + 'Cannot assign ' . $var_id . ' to a mixed type', + new CodeLocation($statements_checker->getSource(), $assign_var) + ), + $statements_checker->getSuppressedIssues() + )) { + // fall through + } } } else { $codebase->analyzer->incrementNonMixedCount($statements_checker->getCheckedFilePath()); diff --git a/tests/PropertyTypeTest.php b/tests/PropertyTypeTest.php index f856cc229..f72d93100 100644 --- a/tests/PropertyTypeTest.php +++ b/tests/PropertyTypeTest.php @@ -828,6 +828,23 @@ class PropertyTypeTest extends TestCase } }', ], + 'allowMixedAssignmetWhenDesired' => [ + 'mixed = $value; + } + }', + ], ]; } @@ -1270,6 +1287,24 @@ class PropertyTypeTest extends TestCase }', 'error_message' => 'InvalidPropertyAssignmentValue', ], + 'prohibitMixedAssignmentNormally' => [ + 'mixed = $value; + } + }', + 'error_message' => 'MixedAssignment', + ], ]; } }