Browse Source

Merge pull request #62688 from cdemirer/assignments-and-types

Fixes https://github.com/godotengine/godot/issues/62650
George Marques 2 years ago
parent
commit
8a98110e3e

+ 10 - 14
modules/gdscript/gdscript_analyzer.cpp

@@ -2262,30 +2262,26 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
 	}
 	p_assignment->set_datatype(op_type);
 
-	if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) {
+	if (assignee_type.is_hard_type() && !assignee_type.is_variant() && op_type.is_hard_type()) {
 		if (compatible) {
 			compatible = is_type_compatible(assignee_type, op_type, true, p_assignment->assigned_value);
 			if (!compatible) {
-				if (assignee_type.is_hard_type()) {
-					// Try reverse test since it can be a masked subtype.
-					if (!is_type_compatible(op_type, assignee_type, true, p_assignment->assigned_value)) {
-						push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", assigned_value_type.to_string(), assignee_type.to_string()), p_assignment->assigned_value);
-					} else {
-						// TODO: Add warning.
-						mark_node_unsafe(p_assignment);
-						p_assignment->use_conversion_assign = true;
-					}
+				// Try reverse test since it can be a masked subtype.
+				if (!is_type_compatible(op_type, assignee_type, true)) {
+					push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", assigned_value_type.to_string(), assignee_type.to_string()), p_assignment->assigned_value);
 				} else {
-					// TODO: Warning in this case.
+					// TODO: Add warning.
 					mark_node_unsafe(p_assignment);
+					p_assignment->use_conversion_assign = true;
 				}
 			}
 		} else {
 			push_error(vformat(R"(Invalid operands "%s" and "%s" for assignment operator.)", assignee_type.to_string(), assigned_value_type.to_string()), p_assignment);
 		}
-	}
-
-	if (assignee_type.has_no_type() || assigned_value_type.is_variant()) {
+	} else if (assignee_type.is_hard_type() && !assignee_type.is_variant()) {
+		mark_node_unsafe(p_assignment);
+		p_assignment->use_conversion_assign = true;
+	} else {
 		mark_node_unsafe(p_assignment);
 		if (assignee_type.is_hard_type() && !assignee_type.is_variant()) {
 			p_assignment->use_conversion_assign = true;

+ 9 - 0
modules/gdscript/tests/scripts/runtime/features/typed_assignment.gd

@@ -0,0 +1,9 @@
+func test():
+	var x: int = 2
+	var y = 3.14
+	var z := 2.72
+	print(typeof(x))
+	x = y
+	print(typeof(x))
+	x = z
+	print(typeof(x))

+ 12 - 0
modules/gdscript/tests/scripts/runtime/features/typed_assignment.out

@@ -0,0 +1,12 @@
+GDTEST_OK
+>> WARNING
+>> Line: 6
+>> NARROWING_CONVERSION
+>> Narrowing conversion (float is converted to int and loses precision).
+>> WARNING
+>> Line: 8
+>> NARROWING_CONVERSION
+>> Narrowing conversion (float is converted to int and loses precision).
+2
+2
+2