1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-14 13:41:12 +00:00

GDScript: Avoid hard errors on inferred types

Since inference isn't always correct, they are now treated as unsafe
instead of errors.

This also removes inferred type when a variable is reassigned. Since
it's not aware of branching, the types might become invalid in a later
context.
This commit is contained in:
George Marques
2021-10-06 11:39:19 -03:00
parent d6c799006a
commit 6bdb28f5e4
5 changed files with 37 additions and 11 deletions

View File

@@ -1742,7 +1742,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
push_error("Cannot assign a new value to a constant.", p_assignment->assignee); push_error("Cannot assign a new value to a constant.", p_assignment->assignee);
} }
if (!assignee_type.is_variant() && !assigned_value_type.is_variant()) { if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) {
bool compatible = true; bool compatible = true;
GDScriptParser::DataType op_type = assigned_value_type; GDScriptParser::DataType op_type = assigned_value_type;
if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
@@ -1794,27 +1794,24 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
case GDScriptParser::IdentifierNode::FUNCTION_PARAMETER: { case GDScriptParser::IdentifierNode::FUNCTION_PARAMETER: {
GDScriptParser::DataType id_type = identifier->parameter_source->get_datatype(); GDScriptParser::DataType id_type = identifier->parameter_source->get_datatype();
if (!id_type.is_hard_type()) { if (!id_type.is_hard_type()) {
id_type = assigned_value_type; id_type.kind = GDScriptParser::DataType::VARIANT;
id_type.type_source = GDScriptParser::DataType::INFERRED; id_type.type_source = GDScriptParser::DataType::UNDETECTED;
id_type.is_constant = false;
identifier->parameter_source->set_datatype(id_type); identifier->parameter_source->set_datatype(id_type);
} }
} break; } break;
case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: { case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: {
GDScriptParser::DataType id_type = identifier->variable_source->get_datatype(); GDScriptParser::DataType id_type = identifier->variable_source->get_datatype();
if (!id_type.is_hard_type()) { if (!id_type.is_hard_type()) {
id_type = assigned_value_type; id_type.kind = GDScriptParser::DataType::VARIANT;
id_type.type_source = GDScriptParser::DataType::INFERRED; id_type.type_source = GDScriptParser::DataType::UNDETECTED;
id_type.is_constant = false;
identifier->variable_source->set_datatype(id_type); identifier->variable_source->set_datatype(id_type);
} }
} break; } break;
case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: { case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: {
GDScriptParser::DataType id_type = identifier->bind_source->get_datatype(); GDScriptParser::DataType id_type = identifier->bind_source->get_datatype();
if (!id_type.is_hard_type()) { if (!id_type.is_hard_type()) {
id_type = assigned_value_type; id_type.kind = GDScriptParser::DataType::VARIANT;
id_type.type_source = GDScriptParser::DataType::INFERRED; id_type.type_source = GDScriptParser::DataType::UNDETECTED;
id_type.is_constant = false;
identifier->variable_source->set_datatype(id_type); identifier->variable_source->set_datatype(id_type);
} }
} break; } break;
@@ -2941,7 +2938,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
} else { } else {
GDScriptParser::DataType base_type = p_subscript->base->get_datatype(); GDScriptParser::DataType base_type = p_subscript->base->get_datatype();
if (base_type.is_variant()) { if (base_type.is_variant() || !base_type.is_hard_type()) {
result_type.kind = GDScriptParser::DataType::VARIANT; result_type.kind = GDScriptParser::DataType::VARIANT;
mark_node_unsafe(p_subscript); mark_node_unsafe(p_subscript);
} else { } else {

View File

@@ -0,0 +1,11 @@
# https://github.com/godotengine/godot/issues/43503
var test_var = null
func test():
print(test_var.x)
func _init():
test_var = Vector3()

View File

@@ -0,0 +1,2 @@
GDTEST_OK
0

View File

@@ -0,0 +1,14 @@
# https://github.com/godotengine/godot/issues/41064
var x = true
func test():
var int_var: int = 0
var dyn_var = 2
if x:
dyn_var = 5
else:
dyn_var = Node.new()
int_var = dyn_var
print(int_var)

View File

@@ -0,0 +1,2 @@
GDTEST_OK
5