Browse Source

GDScript: Allow elements of a parent class in a typed array literal

Dmitrii Maganov 2 years ago
parent
commit
8655d979a1

+ 4 - 0
modules/gdscript/gdscript_analyzer.cpp

@@ -2373,6 +2373,10 @@ void GDScriptAnalyzer::update_array_literal_element_type(GDScriptParser::ArrayNo
 			continue;
 			continue;
 		}
 		}
 		if (!is_type_compatible(p_element_type, element_type, true, p_array)) {
 		if (!is_type_compatible(p_element_type, element_type, true, p_array)) {
+			if (is_type_compatible(element_type, p_element_type)) {
+				mark_node_unsafe(element_node);
+				continue;
+			}
 			push_error(vformat(R"(Cannot have an element of type "%s" in an array of type "Array[%s]".)", element_type.to_string(), p_element_type.to_string()), element_node);
 			push_error(vformat(R"(Cannot have an element of type "%s" in an array of type "Array[%s]".)", element_type.to_string(), p_element_type.to_string()), element_node);
 			return;
 			return;
 		}
 		}

+ 2 - 2
modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd

@@ -116,8 +116,8 @@ func test():
 	assert(duplicated_floats.get_typed_builtin() == TYPE_FLOAT)
 	assert(duplicated_floats.get_typed_builtin() == TYPE_FLOAT)
 
 
 
 
-	var b_objects: Array[B] = [B.new(), null]
-	assert(b_objects.size() == 2)
+	var b_objects: Array[B] = [B.new(), B.new() as A, null]
+	assert(b_objects.size() == 3)
 	assert(b_objects.get_typed_builtin() == TYPE_OBJECT)
 	assert(b_objects.get_typed_builtin() == TYPE_OBJECT)
 	assert(b_objects.get_typed_script() == B)
 	assert(b_objects.get_typed_script() == B)
 
 

+ 7 - 0
modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.gd

@@ -0,0 +1,7 @@
+class Foo: pass
+class Bar extends Foo: pass
+class Baz extends Foo: pass
+
+func test():
+	var typed: Array[Bar] = [Baz.new() as Foo]
+	print('not ok')

+ 7 - 0
modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out

@@ -0,0 +1,7 @@
+GDTEST_RUNTIME_ERROR
+>> ERROR
+>> on function: assign()
+>> core/variant/array.cpp
+>> 222
+>> Method/function failed.
+not ok