godotengine / godotengine/godot
Inconsistent behavior when using signals in ternary-if expressions.
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
v4.2.1.stable.official [b09f793f5]
### System information
Godot v4.2.1.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated AMD Radeon RX 7800 XT (Advanced Micro Devices, Inc.; 31.0.24002.92) - AMD Ryzen 5 5600X 6-Core Processor (12 Threads)
### Issue description
Using `signal.emit()` in ternary-if/else expressions inconsistently throws runtime errors:
**Trying to get a return value of a method that returns "void"**, even though functions with void returns should be allowed in these expressions.
Example of expression:
```gdscript
signal_1.emit() if true else signal_2.emit()
```
Based on some testing the following triggers the error:
- Using the expression in a variable setter:
- Calling a function that executes the expression
The following does not trigger the error:
- Using the expression directly in `_ready()`
- Using the `emit_signal("signal")` syntax
- Evaluating the expression as: `(signal_1 if true else signal_2).emit()`
### Steps to reproduce
Example of code that does not work:
```gdscript
extends Node
signal signal_1
signal signal_2
var test_value: bool:
set(new_value):
signal_1.emit() if true else signal_2.emit()
func _ready() -> void:
signal_1.connect(on_signal_1)
signal_2.connect(on_signal_2)
test_value = true
func on_signal_1() -> void:
print("signal 1 emitted")
func on_signal_2() -> void:
print("signal 2 emitted")
```
Example of code that works.
```gdscript
extends Node
signal signal_1
signal signal_2
var test_value: bool:
set(new_value):
pass
func _ready() -> void:
signal_1.connect(on_signal_1)
signal_2.connect(on_signal_2)
signal_1.emit() if true else signal_2.emit()
func on_signal_1() -> void:
print("signal 1 emitted")
func on_signal_2() -> void:
print("signal 2 emitted")
```
### Minimal reproduction project (MRP)
NA
Contributor guide
Research direction
Start with the provided GDScript reproduction using signal.emit() in a ternary expression inside a variable setter, then compare it with the working _ready(), emit_signal(), and parenthesized forms. Done means the setter and function-call cases no longer raise the void-return runtime error and the expression behaves consistently across these examples.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers, game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100