|
@@ -2001,13 +2001,16 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
|
|
|
}
|
|
|
|
|
|
GDScriptParser::DataType variable_type;
|
|
|
+ String list_visible_type = "<unresolved type>";
|
|
|
if (list_resolved) {
|
|
|
variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
|
|
|
variable_type.kind = GDScriptParser::DataType::BUILTIN;
|
|
|
variable_type.builtin_type = Variant::INT;
|
|
|
+ list_visible_type = "Array[int]"; // NOTE: `range()` has `Array` return type.
|
|
|
} else if (p_for->list) {
|
|
|
resolve_node(p_for->list, false);
|
|
|
GDScriptParser::DataType list_type = p_for->list->get_datatype();
|
|
|
+ list_visible_type = list_type.to_string();
|
|
|
if (!list_type.is_hard_type()) {
|
|
|
mark_node_unsafe(p_for->list);
|
|
|
}
|
|
@@ -2051,8 +2054,37 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
|
|
|
push_error(vformat(R"(Unable to iterate on value of type "%s".)", list_type.to_string()), p_for->list);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
if (p_for->variable) {
|
|
|
- p_for->variable->set_datatype(variable_type);
|
|
|
+ if (p_for->datatype_specifier) {
|
|
|
+ GDScriptParser::DataType specified_type = type_from_metatype(resolve_datatype(p_for->datatype_specifier));
|
|
|
+ if (!specified_type.is_variant()) {
|
|
|
+ if (variable_type.is_variant() || !variable_type.is_hard_type()) {
|
|
|
+ mark_node_unsafe(p_for->variable);
|
|
|
+ p_for->use_conversion_assign = true;
|
|
|
+ } else if (!is_type_compatible(specified_type, variable_type, true, p_for->variable)) {
|
|
|
+ if (is_type_compatible(variable_type, specified_type)) {
|
|
|
+ mark_node_unsafe(p_for->variable);
|
|
|
+ p_for->use_conversion_assign = true;
|
|
|
+ } else {
|
|
|
+ push_error(vformat(R"(Unable to iterate on value of type "%s" with variable of type "%s".)", list_visible_type, specified_type.to_string()), p_for->datatype_specifier);
|
|
|
+ }
|
|
|
+ } else if (!is_type_compatible(specified_type, variable_type)) {
|
|
|
+ p_for->use_conversion_assign = true;
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ } else {
|
|
|
+ parser->push_warning(p_for->datatype_specifier, GDScriptWarning::REDUNDANT_FOR_VARIABLE_TYPE, p_for->variable->name, variable_type.to_string(), specified_type.to_string());
|
|
|
+#endif
|
|
|
+ }
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ } else {
|
|
|
+ parser->push_warning(p_for->datatype_specifier, GDScriptWarning::REDUNDANT_FOR_VARIABLE_TYPE, p_for->variable->name, variable_type.to_string(), specified_type.to_string());
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ p_for->variable->set_datatype(specified_type);
|
|
|
+ } else {
|
|
|
+ p_for->variable->set_datatype(variable_type);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
resolve_suite(p_for->loop);
|