diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 9147204a9bad..a6b4bce000dd 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2665,14 +2665,37 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig #ifdef DEBUG_ENABLED { + bool is_subscript = false; GDScriptParser::ExpressionNode *base = p_assignment->assignee; while (base && base->type == GDScriptParser::Node::SUBSCRIPT) { + is_subscript = true; base = static_cast(base)->base; } if (base && base->type == GDScriptParser::Node::IDENTIFIER) { GDScriptParser::IdentifierNode *id = static_cast(base); if (current_lambda && current_lambda->captures_indices.has(id->name)) { - parser->push_warning(p_assignment, GDScriptWarning::CONFUSABLE_CAPTURE_REASSIGNMENT, id->name); + bool need_warn = false; + if (is_subscript) { + const GDScriptParser::DataType &id_type = id->datatype; + if (id_type.is_hard_type()) { + switch (id_type.kind) { + case GDScriptParser::DataType::BUILTIN: + // TODO: Change `Variant::is_type_shared()` to include packed arrays? + need_warn = !Variant::is_type_shared(id_type.builtin_type) && id_type.builtin_type < Variant::PACKED_BYTE_ARRAY; + break; + case GDScriptParser::DataType::ENUM: + need_warn = true; + break; + default: + break; + } + } + } else { + need_warn = true; + } + if (need_warn) { + parser->push_warning(p_assignment, GDScriptWarning::CONFUSABLE_CAPTURE_REASSIGNMENT, id->name); + } } } } diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd index b1accbe62846..9e1041db54d9 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd @@ -5,23 +5,19 @@ func test(): var string := "1" var vector := Vector2i(1, 0) var array_assign := [1] - var array_append := [1] - var f := func (): - member = 2 - number = 2 - string += "2" - vector.x = 2 - array_assign = [2] - array_append.append(2) - var g := func (): - member = 3 - number = 3 - string += "3" - vector.x = 3 - array_assign = [3] - array_append.append(3) - prints("g", member, number, string, vector, array_assign, array_append) - g.call() - prints("f", member, number, string, vector, array_assign, array_append) - f.call() - prints("test", member, number, string, vector, array_assign, array_append) + var array_index := [1] + var dictionary := { x = 0 } + + var lambda := func (): + member = 2 # Member variable, not captured. + number = 2 # Local variable, captured. + string += "2" # Test compound assignment operator. + vector.x = 2 # Test subscript assignment. + array_assign = [2] # Pass-by-reference type, reassignment. + array_index[0] = 2 # Pass-by-reference type, index access. + dictionary.x = 2 # Pass-by-reference type, attribute access. + + prints("lambda", member, number, string, vector, array_assign, array_index, dictionary) + + lambda.call() + prints("outer", member, number, string, vector, array_assign, array_index, dictionary) diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out index b335a04a02ac..8d953818eb60 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out @@ -1,36 +1,19 @@ GDTEST_OK >> WARNING ->> Line: 11 ->> CONFUSABLE_CAPTURE_REASSIGNMENT ->> Reassigning lambda capture does not modify the outer local variable "number". ->> WARNING ->> Line: 12 ->> CONFUSABLE_CAPTURE_REASSIGNMENT ->> Reassigning lambda capture does not modify the outer local variable "string". ->> WARNING >> Line: 13 >> CONFUSABLE_CAPTURE_REASSIGNMENT ->> Reassigning lambda capture does not modify the outer local variable "vector". +>> Reassigning lambda capture does not modify the outer local variable "number". >> WARNING >> Line: 14 >> CONFUSABLE_CAPTURE_REASSIGNMENT ->> Reassigning lambda capture does not modify the outer local variable "array_assign". ->> WARNING ->> Line: 18 ->> CONFUSABLE_CAPTURE_REASSIGNMENT ->> Reassigning lambda capture does not modify the outer local variable "number". ->> WARNING ->> Line: 19 ->> CONFUSABLE_CAPTURE_REASSIGNMENT >> Reassigning lambda capture does not modify the outer local variable "string". >> WARNING ->> Line: 20 +>> Line: 15 >> CONFUSABLE_CAPTURE_REASSIGNMENT >> Reassigning lambda capture does not modify the outer local variable "vector". >> WARNING ->> Line: 21 +>> Line: 16 >> CONFUSABLE_CAPTURE_REASSIGNMENT >> Reassigning lambda capture does not modify the outer local variable "array_assign". -g 3 3 123 (3, 0) [3] [1, 2, 3] -f 3 2 12 (2, 0) [2] [1, 2, 3] -test 3 1 1 (1, 0) [1] [1, 2, 3] +lambda 2 2 12 (2, 0) [2] [2] { "x": 2 } +outer 2 1 1 (1, 0) [1] [2] { "x": 2 }