From 6d06b3a7d6250cece1c21f7a44312cc97383d99c Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Thu, 27 Nov 2025 13:36:52 +0300 Subject: [PATCH] GDScript: Improve evaluation of constant expressions with arrays/dictionaries --- core/variant/variant.cpp | 20 +- modules/gdscript/gdscript_analyzer.cpp | 335 +++++++++++++----- modules/gdscript/gdscript_analyzer.h | 20 +- .../analyzer/features/constant_expressions.gd | 69 ++++ .../features/constant_expressions.out | 29 ++ .../analyzer/features/type_test_usage.gd | 22 +- .../features/setter_chain_shared_types_2.gd | 31 ++ .../features/setter_chain_shared_types_2.out | 10 + .../gdscript/tests/scripts/utils.notest.gd | 25 +- 9 files changed, 446 insertions(+), 115 deletions(-) create mode 100644 modules/gdscript/tests/scripts/analyzer/features/constant_expressions.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/features/constant_expressions.out create mode 100644 modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types_2.gd create mode 100644 modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types_2.out diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 2b05c84cd8..a42666150a 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -3433,14 +3433,24 @@ bool Variant::is_ref_counted() const { bool Variant::is_type_shared(Variant::Type p_type) { switch (p_type) { case OBJECT: - case ARRAY: case DICTIONARY: + case ARRAY: + // NOTE: Packed array constructors **do** copies (unlike `Array()` and `Dictionary()`), + // whereas they pass by reference when inside a `Variant`. + case PACKED_BYTE_ARRAY: + case PACKED_INT32_ARRAY: + case PACKED_INT64_ARRAY: + case PACKED_FLOAT32_ARRAY: + case PACKED_FLOAT64_ARRAY: + case PACKED_STRING_ARRAY: + case PACKED_VECTOR2_ARRAY: + case PACKED_VECTOR3_ARRAY: + case PACKED_COLOR_ARRAY: + case PACKED_VECTOR4_ARRAY: return true; - default: { - } + default: + return false; } - - return false; } bool Variant::is_shared() const { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 28d4dd5d11..9cddcaded7 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -113,6 +113,8 @@ static GDScriptParser::DataType make_native_meta_type(const StringName &p_class_ return type; } +// WARNING: Use this function **only** to create non-GDScript script metatypes. Otherwise, `check_type_compatibility()` +// may return an incorrect result due to the assumption "A script type cannot be a subtype of a GDScript class". static GDScriptParser::DataType make_script_meta_type(const Ref