From 8400308ab30a2a32731d1c50b53f064edc8cf3ee Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Thu, 2 Feb 2023 00:23:47 +0200 Subject: [PATCH] GDScript: Fix can_reference check for typed arrays --- core/variant/array.cpp | 3 ++ core/variant/container_type_validate.h | 40 ++++++++----------- .../analyzer/features/typed_array_usage.gd | 6 +++ 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 2e1adb91678..d156c353435 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -225,6 +225,9 @@ void Array::assign(const Array &p_array) { _p->array = p_array._p->array; return; } + if (typed.type == Variant::OBJECT || source_typed.type == Variant::OBJECT) { + ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", Variant::get_type_name(source_typed.type), Variant::get_type_name(typed.type))); + } Vector array; array.resize(size); diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h index 796b66dc779..ad679db9d05 100644 --- a/core/variant/container_type_validate.h +++ b/core/variant/container_type_validate.h @@ -41,34 +41,26 @@ struct ContainerTypeValidate { const char *where = "container"; _FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const { - if (type == p_type.type) { - if (type != Variant::OBJECT) { - return true; //nothing else to check - } - } else { + if (type != p_type.type) { + return false; + } else if (type != Variant::OBJECT) { + return true; + } + + if (class_name == StringName()) { + return true; + } else if (p_type.class_name == StringName()) { + return false; + } else if (class_name != p_type.class_name && !ClassDB::is_parent_class(p_type.class_name, class_name)) { return false; } - //both are object - - if ((class_name != StringName()) != (p_type.class_name != StringName())) { - return false; //both need to have class or none - } - - if (class_name != p_type.class_name) { - if (!ClassDB::is_parent_class(p_type.class_name, class_name)) { - return false; - } - } - - if (script.is_null() != p_type.script.is_null()) { + if (script.is_null()) { + return true; + } else if (p_type.script.is_null()) { + return false; + } else if (script != p_type.script && !p_type.script->inherits_script(script)) { return false; - } - - if (script != p_type.script) { - if (!p_type.script->inherits_script(script)) { - return false; - } } return true; diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd index e1e6134fd4f..092ae49d001 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd @@ -201,4 +201,10 @@ func test(): assert(typed_enums.get_typed_builtin() == TYPE_INT) + var a := A.new() + var typed_natives: Array[RefCounted] = [a] + var typed_scripts = Array(typed_natives, TYPE_OBJECT, "RefCounted", A) + assert(typed_scripts[0] == a) + + print('ok')