diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php index 0003a51921d..f4bd5c222be 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php @@ -925,7 +925,7 @@ public static function analyzeAssignmentRef( ) ); } - if (!empty($var_comments)) { + if (!empty($var_comments) && $var_comments[0]->type !== null && $var_comments[0]->var_id === null) { IssueBuffer::maybeAdd( new InvalidDocblock( "Docblock type cannot be used for reference assignment", @@ -990,7 +990,8 @@ public static function analyzeAssignmentRef( $context->vars_in_scope[$lhs_var_id]->parent_nodes[$lhs_node->id] = $lhs_node; - if (($stmt->var instanceof ArrayDimFetch || $stmt->var instanceof PropertyFetch) + if ($statements_analyzer->data_flow_graph !== null + && ($stmt->var instanceof ArrayDimFetch || $stmt->var instanceof PropertyFetch) && $stmt->var->var instanceof Variable && is_string($stmt->var->var->name) ) { @@ -1006,6 +1007,15 @@ public static function analyzeAssignmentRef( : "property-assignment-as-reference" ); } + + if ($root_var_id === '$this') { + // Variables on `$this` are always used + $statements_analyzer->data_flow_graph->addPath( + $lhs_node, + new DataFlowNode('variable-use', 'variable use', null), + 'variable-use', + ); + } } if ($stmt->var instanceof ArrayDimFetch) { diff --git a/tests/ReferenceTest.php b/tests/ReferenceTest.php index af50a5ebee0..56569774505 100644 --- a/tests/ReferenceTest.php +++ b/tests/ReferenceTest.php @@ -247,6 +247,16 @@ function func(array &$a): void ', 'assertions' => [], ], + 'allowDocblockTypingOtherVariable' => [ + 'code' => ' [ + '$b' => 'string', + ], + ], ]; } diff --git a/tests/UnusedVariableTest.php b/tests/UnusedVariableTest.php index b536ad4dca2..a6767d8e200 100644 --- a/tests/UnusedVariableTest.php +++ b/tests/UnusedVariableTest.php @@ -2587,6 +2587,20 @@ function takesAnInt(): void { } }', ], + 'referenceInPropertyIsNotUnused' => [ + 'code' => 'bar = &$ref; + } + } + ', + ], ]; }