You've already forked godot
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:
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
GDTEST_OK
|
||||||
|
0
|
||||||
@@ -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)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
GDTEST_OK
|
||||||
|
5
|
||||||
Reference in New Issue
Block a user