From 81c7cae56782b73f7d9881763607582ff2b51a29 Mon Sep 17 00:00:00 2001 From: George Marques Date: Tue, 1 Jul 2025 12:28:26 -0300 Subject: [PATCH] GDScript: Don't get invalid dictionary key during completion We try to get the value out of a dictionary in order to establish its type for completion purposes. However, if the dictionary or the key is not a constant, we cannot safely get the actual value, so we skip this and just try to infer from static typing. Getting the value directly with `Variant::get()` generate errors if the base is a Dictionary and the key is of an invalid type. So before trying to get it we use the Dictionary validator to make sure it we can safely try to get the key. --- modules/gdscript/gdscript_editor.cpp | 24 +++++++++++++------ .../typed_array_assign_wrong_to_typed.out | 2 +- ...typed_dictionary_assign_wrong_to_typed.out | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 3612cb81c3c..0f69314d8cb 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -44,6 +44,7 @@ #include "core/core_constants.h" #include "core/io/file_access.h" #include "core/math/expression.h" +#include "core/variant/container_type_validate.h" #ifdef TOOLS_ENABLED #include "core/config/project_settings.h" @@ -2099,13 +2100,22 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, break; } - { - bool valid; - Variant value = base.value.get(index.value, &valid); - if (valid) { - r_type = _type_from_variant(value, p_context); - found = true; - break; + if (base.type.is_constant && index.type.is_constant) { + if (base.value.get_type() == Variant::DICTIONARY) { + Dictionary base_dict = base.value.operator Dictionary(); + if (base_dict.get_key_validator().test_validate(index.value) && base_dict.has(index.value)) { + r_type = _type_from_variant(base_dict[index.value], p_context); + found = true; + break; + } + } else { + bool valid; + Variant value = base.value.get(index.value, &valid); + if (valid) { + r_type = _type_from_variant(value, p_context); + found = true; + break; + } } } diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out index b142798f4c8..c1404310120 100644 --- a/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out +++ b/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out @@ -1,5 +1,5 @@ GDTEST_RUNTIME_ERROR ->> ERROR: Condition "!other_script->inherits_script(script)" is true. Returning: false +>> ERROR: Method/function failed. Returning: false >> Attempted to assign an object into a TypedArray, that does not inherit from 'GDScript'. >> ERROR: Method/function failed. >> Unable to convert array index 0 from "Object" to "Object". diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out index 495c5b7a341..11ba1c06e50 100644 --- a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out +++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out @@ -1,5 +1,5 @@ GDTEST_RUNTIME_ERROR ->> ERROR: Condition "!other_script->inherits_script(script)" is true. Returning: false +>> ERROR: Method/function failed. Returning: false >> Attempted to assign an object into a TypedDictionary.Key, that does not inherit from 'GDScript'. >> ERROR: Method/function failed. >> Unable to convert key from "Object" to "Object".