You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The recently added static typing for for loop variables here #80247 has a weird quirk that I feel like I may be considered a bug, or at least strange behavior.
If you are looping over an array that contains node references, and one of those nodes gets freed, <Freed Object> remains in its index. While normally you can use is_instance_valid() for validating your node references, trying to do this in a typed for loop will fail with the error "Trying to assign invalid previously freed instance" at the "for" line, before it even gets to where you can validate it. However, it's possible to get around this by removing the type from the loop variable and checking it after the instance is validated, but that then makes typing the loop variable questionable in the first place. Since I think that may be unclear, here's some example code of what I mean:
# Tested with an Array with some generic Node2Dsvarobjects_to_be_freed: Array=get_tree().get_nodes_in_group("object_freeing")
# After any of those nodes is freed...# Runs without errorforobjectinobjects_to_be_freed:
ifis_instance_valid(object):
print("Valid!")
else:
print("Invalid!")
# Will cause error: "Trying to assign invalid previously freed instance"forobject: Node2Dinobjects_to_be_freed: # Errors at this lineifis_instance_valid(object): # I would expect this line to be how to catch the invalid reference before errorprint("Valid!")
else:
print("Invalid!")
# Runs without error and effectively keeps static typing as far as I can tellforobjectinobjects_to_be_freed:
ifis_instance_valid(object) andobjectisNode2D:
print("Valid!")
else:
print("Invalid!")
This makes me wonder if this behavior is intended, and if it is intended, why? The 3rd block (the workaround) seems like it would be the best way to handle this in all cases, and if that's the case, then why isn't the first block just interpreted the same way by the engine?
I would expect the first block to work without error as written, simply printing "Invalid!" if the object was freed.
Steps to reproduce
Make an array, add node references to it, free any of the nodes without clearing the reference, create a for loop to iterate over that array, and make the for loop variable typed to those nodes. Tested this with the code snippet in the issue description.
Minimal reproduction project (MRP)
N/A
The text was updated successfully, but these errors were encountered:
I realized that I made a mistake in my third code block, as that actually does not provide autocomplete quite the same as I believed when both of these checks are on the same line:
ifis_instance_valid(object) andobjectisNode2D:
So it would need to look something even more convoluted like this to more achieve the same desired purpose:
# Runs without error and effectively keeps static typing as far as I can tellforobjectinobjects_to_be_freed:
ifnotis_instance_valid(object):
print("Invalid!")
continueifobjectisNode2D: # now you get static typing benefits like autocompleteprint("Valid!")
Which is getting really silly.
That said, I think the PR dalexeev mentioned seems like it would solve this issue regardless.
Tested versions
v4.3.stable.official [77dcf97]
System information
Godot v4.3.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 (NVIDIA; 32.0.15.6636) - AMD Ryzen 5 7600X 6-Core Processor (12 Threads)
Issue description
v4.3.stable.official [77dcf97]
The recently added static typing for for loop variables here #80247 has a weird quirk that I feel like I may be considered a bug, or at least strange behavior.
If you are looping over an array that contains node references, and one of those nodes gets freed,
<Freed Object>
remains in its index. While normally you can useis_instance_valid()
for validating your node references, trying to do this in a typed for loop will fail with the error "Trying to assign invalid previously freed instance" at the "for" line, before it even gets to where you can validate it. However, it's possible to get around this by removing the type from the loop variable and checking it after the instance is validated, but that then makes typing the loop variable questionable in the first place. Since I think that may be unclear, here's some example code of what I mean:This makes me wonder if this behavior is intended, and if it is intended, why? The 3rd block (the workaround) seems like it would be the best way to handle this in all cases, and if that's the case, then why isn't the first block just interpreted the same way by the engine?
I would expect the first block to work without error as written, simply printing "Invalid!" if the object was freed.
Steps to reproduce
Make an array, add node references to it, free any of the nodes without clearing the reference, create a for loop to iterate over that array, and make the for loop variable typed to those nodes. Tested this with the code snippet in the issue description.
Minimal reproduction project (MRP)
N/A
The text was updated successfully, but these errors were encountered: