Browse Source

Merge pull request #70987 from vonagam/fix-parameter-conversion-assign

George Marques 2 years ago
parent
commit
75515e4303

+ 3 - 6
modules/gdscript/gdscript_analyzer.cpp

@@ -1514,7 +1514,6 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi
 	GDScriptParser::DataType type;
 	type.kind = GDScriptParser::DataType::VARIANT;
 
-	bool is_variable = p_assignable->type == GDScriptParser::Node::VARIABLE;
 	bool is_constant = p_assignable->type == GDScriptParser::Node::CONSTANT;
 
 	GDScriptParser::DataType specified_type;
@@ -1576,13 +1575,11 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi
 		} else if (!specified_type.is_variant()) {
 			if (initializer_type.is_variant() || !initializer_type.is_hard_type()) {
 				mark_node_unsafe(p_assignable->initializer);
-				if (is_variable) {
-					static_cast<GDScriptParser::VariableNode *>(p_assignable)->use_conversion_assign = true;
-				}
+				p_assignable->use_conversion_assign = true;
 			} else if (!is_type_compatible(specified_type, initializer_type, true, p_assignable->initializer)) {
-				if (is_variable && is_type_compatible(initializer_type, specified_type, true, p_assignable->initializer)) {
+				if (!is_constant && is_type_compatible(initializer_type, specified_type, true, p_assignable->initializer)) {
 					mark_node_unsafe(p_assignable->initializer);
-					static_cast<GDScriptParser::VariableNode *>(p_assignable)->use_conversion_assign = true;
+					p_assignable->use_conversion_assign = true;
 				} else {
 					push_error(vformat(R"(Cannot assign a value of type %s to %s "%s" with specified type %s.)", initializer_type.to_string(), p_kind, p_assignable->identifier->name, specified_type.to_string()), p_assignable->initializer);
 				}

+ 6 - 2
modules/gdscript/gdscript_byte_codegen.cpp

@@ -872,8 +872,12 @@ void GDScriptByteCodeGenerator::write_assign_false(const Address &p_target) {
 	append(p_target);
 }
 
-void GDScriptByteCodeGenerator::write_assign_default_parameter(const Address &p_dst, const Address &p_src) {
-	write_assign(p_dst, p_src);
+void GDScriptByteCodeGenerator::write_assign_default_parameter(const Address &p_dst, const Address &p_src, bool p_use_conversion) {
+	if (p_use_conversion) {
+		write_assign_with_conversion(p_dst, p_src);
+	} else {
+		write_assign(p_dst, p_src);
+	}
 	function->default_arguments.push_back(opcodes.size());
 }
 

+ 1 - 1
modules/gdscript/gdscript_byte_codegen.h

@@ -460,7 +460,7 @@ public:
 	virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) override;
 	virtual void write_assign_true(const Address &p_target) override;
 	virtual void write_assign_false(const Address &p_target) override;
-	virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override;
+	virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src, bool p_use_conversion) override;
 	virtual void write_store_global(const Address &p_dst, int p_global_index) override;
 	virtual void write_store_named_global(const Address &p_dst, const StringName &p_global) override;
 	virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) override;

+ 1 - 1
modules/gdscript/gdscript_codegen.h

@@ -113,7 +113,7 @@ public:
 	virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) = 0;
 	virtual void write_assign_true(const Address &p_target) = 0;
 	virtual void write_assign_false(const Address &p_target) = 0;
-	virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0;
+	virtual void write_assign_default_parameter(const Address &dst, const Address &src, bool p_use_conversion) = 0;
 	virtual void write_store_global(const Address &p_dst, int p_global_index) = 0;
 	virtual void write_store_named_global(const Address &p_dst, const StringName &p_global) = 0;
 	virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) = 0;

+ 1 - 1
modules/gdscript/gdscript_compiler.cpp

@@ -2116,7 +2116,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
 					}
 				}
 
-				codegen.generator->write_assign_default_parameter(dst_addr, src_addr);
+				codegen.generator->write_assign_default_parameter(dst_addr, src_addr, parameter->use_conversion_assign);
 				if (src_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
 					codegen.generator->pop_temporary();
 				}

+ 1 - 1
modules/gdscript/gdscript_parser.h

@@ -360,6 +360,7 @@ public:
 		ExpressionNode *initializer = nullptr;
 		TypeNode *datatype_specifier = nullptr;
 		bool infer_datatype = false;
+		bool use_conversion_assign = false;
 		int usages = 0;
 
 		virtual ~AssignableNode() {}
@@ -1182,7 +1183,6 @@ public:
 		bool onready = false;
 		PropertyInfo export_info;
 		int assignments = 0;
-		bool use_conversion_assign = false;
 #ifdef TOOLS_ENABLED
 		String doc_description;
 #endif // TOOLS_ENABLED

+ 8 - 0
modules/gdscript/tests/scripts/runtime/errors/bad_conversion_for_default_parameter.gd

@@ -0,0 +1,8 @@
+var weakling = 'not float'
+func weak(x: float = weakling):
+	print(x)
+	print('typeof x is', typeof(x))
+
+func test():
+	print(typeof(weak()))
+	print('not ok')

+ 8 - 0
modules/gdscript/tests/scripts/runtime/errors/bad_conversion_for_default_parameter.out

@@ -0,0 +1,8 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: weak()
+>> runtime/errors/bad_conversion_for_default_parameter.gd
+>> 2
+>> Trying to assign value of type 'String' to a variable of type 'float'.
+0
+not ok

+ 19 - 0
modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.gd

@@ -0,0 +1,19 @@
+func literal(x: float = 1):
+	print('x is ', x)
+	print('typeof x is ', typeof(x))
+
+var inferring := 2
+func inferred(x: float = inferring):
+	print('x is ', x)
+	print('typeof x is ', typeof(x))
+
+var weakling = 3
+func weak(x: float = weakling):
+	print('x is ', x)
+	print('typeof x is ', typeof(x))
+
+func test():
+	literal()
+	inferred()
+	weak()
+	print('ok')

+ 8 - 0
modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out

@@ -0,0 +1,8 @@
+GDTEST_OK
+x is 1
+typeof x is 3
+x is 2
+typeof x is 3
+x is 3
+typeof x is 3
+ok