diff options
author | Danil Alexeev <danil@alexeev.xyz> | 2023-09-21 11:14:28 +0300 |
---|---|---|
committer | Danil Alexeev <danil@alexeev.xyz> | 2023-09-21 11:25:59 +0300 |
commit | 3c35e7f1d6ff3aaed360afca3ba1638ec4335aec (patch) | |
tree | ffb9b54015afe043893e99b85ceeb8bbcc6b232c /modules/gdscript/gdscript_analyzer.cpp | |
parent | 59139df16e7a10c3b9176f697d23b557af46601e (diff) | |
download | redot-engine-3c35e7f1d6ff3aaed360afca3ba1638ec4335aec.tar.gz |
GDScript: Make array literal typed if `for` loop variable type is specified
Diffstat (limited to 'modules/gdscript/gdscript_analyzer.cpp')
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 04c86d60a8..866eb061cb 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2143,6 +2143,9 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) { } else if (!is_type_compatible(specified_type, variable_type)) { p_for->use_conversion_assign = true; } + if (p_for->list && p_for->list->type == GDScriptParser::Node::ARRAY) { + update_array_literal_element_type(static_cast<GDScriptParser::ArrayNode *>(p_for->list), specified_type); + } } p_for->variable->set_datatype(specified_type); } else { @@ -2541,28 +2544,31 @@ void GDScriptAnalyzer::update_const_expression_builtin_type(GDScriptParser::Expr // When an array literal is stored (or passed as function argument) to a typed context, we then assume the array is typed. // This function determines which type is that (if any). void GDScriptAnalyzer::update_array_literal_element_type(GDScriptParser::ArrayNode *p_array, const GDScriptParser::DataType &p_element_type) { + GDScriptParser::DataType expected_type = p_element_type; + expected_type.unset_container_element_type(); // Nested types (like `Array[Array[int]]`) are not currently supported. + for (int i = 0; i < p_array->elements.size(); i++) { GDScriptParser::ExpressionNode *element_node = p_array->elements[i]; if (element_node->is_constant) { - update_const_expression_builtin_type(element_node, p_element_type, "include"); + update_const_expression_builtin_type(element_node, expected_type, "include"); } - const GDScriptParser::DataType &element_type = element_node->get_datatype(); - if (element_type.has_no_type() || element_type.is_variant() || !element_type.is_hard_type()) { + const GDScriptParser::DataType &actual_type = element_node->get_datatype(); + if (actual_type.has_no_type() || actual_type.is_variant() || !actual_type.is_hard_type()) { mark_node_unsafe(element_node); continue; } - if (!is_type_compatible(p_element_type, element_type, true, p_array)) { - if (is_type_compatible(element_type, p_element_type)) { + if (!is_type_compatible(expected_type, actual_type, true, p_array)) { + if (is_type_compatible(actual_type, expected_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]".)", actual_type.to_string(), expected_type.to_string()), element_node); return; } } GDScriptParser::DataType array_type = p_array->get_datatype(); - array_type.set_container_element_type(p_element_type); + array_type.set_container_element_type(expected_type); p_array->set_datatype(array_type); } |