godot-rust / godot-rust/gdext

Engine signals with `Gd<T>` parameters can receive null

Open
#1,663 2 comments 0 reactions 0 assignees View on GitHub
bug c: engine
Dominant language
Rust
Stars
5.2k
Forks
312
Avg merge
12h 59m
Merged PRs (30d)
9

Description

Signal parameters of object type are generated as `Gd`, which is non-nullable. But Godot passes `null` for some of them, so
connecting a handler to such a signal can panic and isn't easily avoidable by the user.

The clearest case is `EditorPlugin::scene_changed`, whose `scene_root` is null when the last scene tab is closed:

```rust
#[godot_api]
impl IEditorPlugin for MyPlugin {
fn enter_tree(&mut self) {
self.signals()
.scene_changed()
.connect(|scene_root: Gd| {
// Never runs -- closing the last scene tab passes null, and conversion panics before we get here.
godot_print!("now editing {scene_root}");
});
}
}
```

`EditorPlugin::resource_saved` (`resource: Resource`) has the same problem. There are likely more.

---

Some ideas:

1. Use `Option>` everywhere.
- Technically correct, but requires `unwrap()` even if object parameters are guaranteed non-null.

2. Keep `Gd`, add a `*_nullable` overload with `Option>`, deprecating the original.
- Can be added incrementally, as users report problems.
- Increases API surface, deprecation churn.
- Note: nullability is per-object, not per-signal. Needs decision on what to do for signals with multiple object parameters.
3. Same signal uses either `Gd` or `Option` (exclusive).
- Hand-maintained list of affected `(class, signal, parameter)` triples in `godot-codegen/src/special_cases.rs` (but also true for other approaches).
- Needs ahead-of-time work to find out which are nullable and which not; hard to correct later without minor version bump.

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the signal parameter generation and the proposed hand-maintained list in godot-codegen/src/special_cases.rs, using EditorPlugin::scene_changed and EditorPlugin::resource_saved as concrete cases. Determine and document the nullability strategy before changing the affected bindings. Done means nullable Godot object signal parameters no longer panic when Godot passes null, while non-nullable parameters retain appropriate handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev, tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.