mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 23:21:15 +00:00 
			
		
		
		
	GDScript: Fix implicit conversions for function returns
This commit is contained in:
		
							parent
							
								
									218bef90af
								
							
						
					
					
						commit
						6194a7e0fa
					
				
					 3 changed files with 52 additions and 21 deletions
				
			
		| 
						 | 
					@ -1958,11 +1958,9 @@ void GDScriptAnalyzer::resolve_return(GDScriptParser::ReturnNode *p_return) {
 | 
				
			||||||
	GDScriptParser::DataType result;
 | 
						GDScriptParser::DataType result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GDScriptParser::DataType expected_type;
 | 
						GDScriptParser::DataType expected_type;
 | 
				
			||||||
	bool has_expected_type = false;
 | 
						bool has_expected_type = parser->current_function != nullptr;
 | 
				
			||||||
 | 
						if (has_expected_type) {
 | 
				
			||||||
	if (parser->current_function != nullptr) {
 | 
					 | 
				
			||||||
		expected_type = parser->current_function->get_datatype();
 | 
							expected_type = parser->current_function->get_datatype();
 | 
				
			||||||
		has_expected_type = true;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (p_return->return_value != nullptr) {
 | 
						if (p_return->return_value != nullptr) {
 | 
				
			||||||
| 
						 | 
					@ -1985,26 +1983,23 @@ void GDScriptAnalyzer::resolve_return(GDScriptParser::ReturnNode *p_return) {
 | 
				
			||||||
		result.is_constant = true;
 | 
							result.is_constant = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (has_expected_type) {
 | 
						if (has_expected_type && !expected_type.is_variant()) {
 | 
				
			||||||
		expected_type.is_meta_type = false;
 | 
							if (result.is_variant() || !result.is_hard_type()) {
 | 
				
			||||||
		if (expected_type.is_hard_type()) {
 | 
								mark_node_unsafe(p_return);
 | 
				
			||||||
			if (!is_type_compatible(expected_type, result)) {
 | 
								if (!is_type_compatible(expected_type, result, true, p_return)) {
 | 
				
			||||||
				// Try other way. Okay but not safe.
 | 
									downgrade_node_type_source(p_return);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (!is_type_compatible(expected_type, result, true, p_return)) {
 | 
				
			||||||
 | 
								mark_node_unsafe(p_return);
 | 
				
			||||||
			if (!is_type_compatible(result, expected_type)) {
 | 
								if (!is_type_compatible(result, expected_type)) {
 | 
				
			||||||
				push_error(vformat(R"(Cannot return value of type "%s" because the function return type is "%s".)", result.to_string(), expected_type.to_string()), p_return);
 | 
									push_error(vformat(R"(Cannot return value of type "%s" because the function return type is "%s".)", result.to_string(), expected_type.to_string()), p_return);
 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					// TODO: Add warning.
 | 
					 | 
				
			||||||
					mark_node_unsafe(p_return);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
#ifdef DEBUG_ENABLED
 | 
					#ifdef DEBUG_ENABLED
 | 
				
			||||||
		} else if (expected_type.builtin_type == Variant::INT && result.builtin_type == Variant::FLOAT) {
 | 
							} else if (expected_type.builtin_type == Variant::INT && result.builtin_type == Variant::FLOAT) {
 | 
				
			||||||
			parser->push_warning(p_return, GDScriptWarning::NARROWING_CONVERSION);
 | 
								parser->push_warning(p_return, GDScriptWarning::NARROWING_CONVERSION);
 | 
				
			||||||
			} else if (result.is_variant() && !expected_type.is_variant()) {
 | 
					 | 
				
			||||||
				mark_node_unsafe(p_return);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p_return->set_datatype(result);
 | 
						p_return->set_datatype(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					func convert_literal_int_to_float() -> float: return 76
 | 
				
			||||||
 | 
					func convert_arg_int_to_float(arg: int) -> float: return arg
 | 
				
			||||||
 | 
					func convert_var_int_to_float() -> float: var number := 59; return number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func convert_literal_array_to_packed() -> PackedStringArray: return ['46']
 | 
				
			||||||
 | 
					func convert_arg_array_to_packed(arg: Array) -> PackedStringArray: return arg
 | 
				
			||||||
 | 
					func convert_var_array_to_packed() -> PackedStringArray: var array := ['79']; return array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func test():
 | 
				
			||||||
 | 
						var converted_literal_int := convert_literal_int_to_float()
 | 
				
			||||||
 | 
						assert(typeof(converted_literal_int) == TYPE_FLOAT)
 | 
				
			||||||
 | 
						assert(converted_literal_int == 76.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var converted_arg_int := convert_arg_int_to_float(36)
 | 
				
			||||||
 | 
						assert(typeof(converted_arg_int) == TYPE_FLOAT)
 | 
				
			||||||
 | 
						assert(converted_arg_int == 36.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var converted_var_int := convert_var_int_to_float()
 | 
				
			||||||
 | 
						assert(typeof(converted_var_int) == TYPE_FLOAT)
 | 
				
			||||||
 | 
						assert(converted_var_int == 59.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var converted_literal_array := convert_literal_array_to_packed()
 | 
				
			||||||
 | 
						assert(typeof(converted_literal_array) == TYPE_PACKED_STRING_ARRAY)
 | 
				
			||||||
 | 
						assert(str(converted_literal_array) == '["46"]')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var converted_arg_array := convert_arg_array_to_packed(['91'])
 | 
				
			||||||
 | 
						assert(typeof(converted_arg_array) == TYPE_PACKED_STRING_ARRAY)
 | 
				
			||||||
 | 
						assert(str(converted_arg_array) == '["91"]')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var converted_var_array := convert_var_array_to_packed()
 | 
				
			||||||
 | 
						assert(typeof(converted_var_array) == TYPE_PACKED_STRING_ARRAY)
 | 
				
			||||||
 | 
						assert(str(converted_var_array) == '["79"]')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						print('ok')
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					GDTEST_OK
 | 
				
			||||||
 | 
					ok
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue