godotengine / godotengine/godot

Inconsistent behavior when using signals in ternary-if expressions.

Open
#89,237 2 comments 0 reactions 0 assignees View on GitHub
bug confirmed topic:gdscript
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.