-
-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDScript: Fix type compatibility check between Array[T]
and Packed*Array
s
#99950
base: master
Are you sure you want to change the base?
Conversation
… Array[T], where T != Vector2
@@ -6054,6 +6054,17 @@ bool GDScriptAnalyzer::check_type_compatibility(const GDScriptParser::DataType & | |||
valid = p_target.get_container_element_type(0) == p_source.get_container_element_type(0); | |||
} | |||
} | |||
if (valid && p_target.builtin_type != Variant::ARRAY && p_source.builtin_type == Variant::ARRAY) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only checks for p_target.builtin_type != Variant::ARRAY
so anything that isn't an Array. That would include all other Variant types including Dictionary, float, etc., no?
Also note, once the correct approach is found here, a similar check should likely be done for typed Dictionaries just below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a lil confusing, but the implementation of the Variant::can_convert_strict
call above here (line 6045) guarantees that if valid == true
, and p_source is an ARRAY
, then p_target is either an ARRAY or a PACKED_ARRAY
. I will try to make this more explicit, since this could be a bug farm if the implementation of Variant::can_convert_strict
changes.
container_type.type_source = p_target.type_source; | ||
valid = p_source.get_container_element_type(0) == container_type; | ||
} else { | ||
// don't support converting a non-static array into a packed array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// don't support converting a non-static array into a packed array | |
// Don't support converting a non-static array into a packed array. |
var array: Array[int] | ||
var packed_array: PackedVector2Array | ||
|
||
# these types should not be compatible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# these types should not be compatible | |
# These types should not be compatible. |
Array[T]
and Packed*Array
s
Note that this is "obvious" only for array literals with invalid elements. Instead of: var array: PackedVector2Array
array = ["abc", "def"] it could be: var array: PackedVector2Array
array = [Vector2(), Vector2()] var array: PackedVector2Array
array = [vector2_expr, vector2_expr] var array: PackedVector2Array
array = [variant_expr, variant_expr] var array: PackedVector2Array
array = array_expr If the analyzer cannot guarantee that the assigned |
@dalexeev That is not currently how it works when converting from Based on what you said, I think the above screenshot should succeed since the elements of I see two paths here. Regardless, I want to keep the behavior of
How should I proceed? |
I agree that this behavior can be confusing, but there is a difference between implicit conversions Arrays are passed by reference and untyped arrays can reference typed ones. This exception was made for compatibility with 3.x and for the convenience untyped GDScript users.
Unlike the |
Closes #94454
Verifies that, when assigning an Array to a PackedArray, that the array element is compatible with the packed array's element.
This is a potentially breaking change. Before this change, the invalid type would be converted to a default value. In this example, the packed array would silently become
[(0,0), (0,0)]
. This could be mitigated with a warning but I believe the proper behavior is to spout an error.