Skip to content
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 2.0: Static typing on signals isn't enforced #54333

Open
AaronRecord opened this issue Oct 28, 2021 · 12 comments · May be fixed by #71952
Open

GDScript 2.0: Static typing on signals isn't enforced #54333

AaronRecord opened this issue Oct 28, 2021 · 12 comments · May be fixed by #71952
Assignees
Milestone

Comments

@AaronRecord
Copy link
Contributor

AaronRecord commented Oct 28, 2021

Godot version

v4.0.dev.custom_build [a851012b1]

System information

Windows 10

Issue description

The following code:

signal test(a: Node2D, b: Camera3D)

func _ready():
	test.connect(func(a, b): print(a + b))
	test.emit(Vector2.UP, Vector2.RIGHT)

compiles without any errors, and prints (1, -1).


It should produce an error, something like:

Invalid argument for "emit()" function: argument 1 should be Node2D but is Vector2.
Invalid argument for "emit()" function: argument 2 should be Camera3D but is Vector2.

Steps to reproduce

See above.

Minimal reproduction project

No response

@AaronRecord AaronRecord changed the title [GDScript 2.0] Static typing on signals isn't enforced GDScript 2.0: Static typing on signals isn't enforced Oct 28, 2021
@akien-mga
Copy link
Member

Duplicate of godotengine/godot-proposals#2557.

@AaronRecord
Copy link
Contributor Author

AaronRecord commented Oct 28, 2021

Duplicate of godotengine/godot-proposals#2557.

I was aware of that issue, the weird part is that is accepts type arguments without complaint, it just doesn't use them. On 3.x you get an error if you try to add types to signal arguments. So if this won't be supported for 4.0 then the ability to add types to signal arguments should be removed.

@akien-mga akien-mga reopened this Oct 28, 2021
@akien-mga akien-mga added this to the 4.0 milestone Oct 28, 2021
@Calinou
Copy link
Member

Calinou commented Oct 28, 2021

See also #52083 (comment).

@vnen vnen self-assigned this Nov 10, 2021
@dalexeev
Copy link
Member

See also godotengine/godot-proposals#2557 (comment).

@AaronRecord
Copy link
Contributor Author

AaronRecord commented Nov 20, 2021

See also godotengine/godot-proposals#2557 (comment).

Okay, but at the very least this limitation should be documented before this issue is closed, otherwise it's quite counterintuitive as many users will expect the types to be enforced.

@Calinou Calinou linked a pull request Feb 1, 2023 that will close this issue
5 tasks
@adamscott
Copy link
Member

@vnen I would push this issue to 4.x or 4.1

@akien-mga akien-mga modified the milestones: 4.0, 4.x Feb 24, 2023
@qaptoR
Copy link

qaptoR commented Apr 11, 2023

Bumping this as relatively important for the following reason:

When checking the types for the argument list of a signal against those of the parameter list for a potential method that will connect.

In this instance, for every built-in signal there are types, for custom signals the types are all '0'.
This is inconsistent behaviour as custom signals should have the same functionality as built in signals.

@dalexeev
Copy link
Member

This is inconsistent behaviour as custom signals should have the same functionality as built in signals.

There is no protection for built-in signals either, you can emit a signal with any arguments. The only "protection" is callback type hints. The difference from built-in signals is that the editor does not currently use this information when generating a custom signal callback. But this can be considered a bug that we need to fix.

extends Node

func _ready() -> void:
    child_entered_tree.connect(_on_child_entered_tree)
    child_entered_tree.emit(42, [], NAN) # No error.

#func _on_child_entered_tree(node: Node) -> void:
#    pass

func _on_child_entered_tree(a, b, c) -> void:
    prints(a, b, c)

@vnen
Copy link
Member

vnen commented Apr 11, 2023

In this instance, for every built-in signal there are types, for custom signals the types are all '0'.
This is inconsistent behaviour as custom signals should have the same functionality as built in signals.

BTW this isn't related to enforcing types on signals, this is only because script info is not being populated properly for all the get_*() functions. It's the same problem as #67544

@FabriceCastel
Copy link

Wanted to chime in with an example as to why this feature is important. I had the following code:

# event_bus.gd
signal on_update_letters(word: String, letters: Array[bool])

# level.gd
func _ready():
	var word = "ICY"
	var letters = [false, false, false]
	EventBus.on_update_letters.emit(word, letters)

# level_ui.gd
func _ready():
	EventBus.connect("on_update_letters", on_update_letters)

func on_update_letters(word: String, letters: Array[bool]):
	print("This should get printed, but it never gets invoked")

Can you spot the bug?

on_update_letters in level_ui.gd never gets called because letters in level.gd is NOT an Array[bool]. Don't know why, honestly, but changing that line to var letters: Array[bool] = [false, false, false] resolves the issue.

It's way too easy for minor type mistakes to lead to silent failures, and they're extremely annoying to debug. I haven't had to do any refactoring work around signals yet, but I'd bet my bottom dollar that it can be a similarly frustrating debugging experience.

Calling emit on a signal with params that do not match the types in its declaration shouldn't fail silently.

@vnen vnen added discussion and removed bug labels Feb 8, 2024
@vnen
Copy link
Member

vnen commented Feb 8, 2024

So, this is not really a bug. It could be changed but it is like so by design because the core never enforced types either. The types you can set are only for documentation purposes, at least for now, the same as they are in core.

@dalexeev
Copy link
Member

dalexeev commented Feb 8, 2024

The difference from built-in signals is that the editor does not currently use this information when generating a custom signal callback. But this can be considered a bug that we need to fix.

Fixed in #79366 and others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants