diff options
author | George Marques <george@gmarqu.es> | 2023-01-12 11:34:13 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-12 11:34:13 -0300 |
commit | 75515e43034aab3acd014bf6c663c10fcba94900 (patch) | |
tree | b7b87a41c77fafa85934d0e703830033ad926557 /modules/gdscript | |
parent | 7319fa60825ec2e530fe843897b350e6012ae461 (diff) | |
parent | a8c2f8a0e1c4d4e128bd64084f5e5611005a923d (diff) |
Merge pull request #70987 from vonagam/fix-parameter-conversion-assign
Diffstat (limited to 'modules/gdscript')
10 files changed, 56 insertions, 12 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 6fb1abaf84..0b0eb4170f 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/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); } diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 57ee41e34e..6c80fb7665 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/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()); } diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index ac9c4c8fb5..171c505116 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/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; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index c7a1bcb9e9..e885938eba 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/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; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index beed6e90d2..77c6690d20 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/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(); } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 4bb02c4ea3..0903f62061 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/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 diff --git a/modules/gdscript/tests/scripts/runtime/errors/bad_conversion_for_default_parameter.gd b/modules/gdscript/tests/scripts/runtime/errors/bad_conversion_for_default_parameter.gd new file mode 100644 index 0000000000..a72ac9b5ee --- /dev/null +++ b/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') diff --git a/modules/gdscript/tests/scripts/runtime/errors/bad_conversion_for_default_parameter.out b/modules/gdscript/tests/scripts/runtime/errors/bad_conversion_for_default_parameter.out new file mode 100644 index 0000000000..8543cf976e --- /dev/null +++ b/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 diff --git a/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.gd b/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.gd new file mode 100644 index 0000000000..9d0c6317b3 --- /dev/null +++ b/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') diff --git a/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out b/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out new file mode 100644 index 0000000000..a9ef4919cf --- /dev/null +++ b/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 |