godot-rust / godot-rust/gdext

Panic in Debug impl of GDScriptNativeClass

Open
#1,690 1 comment 0 reactions 0 assignees View on GitHub
bug c: core
Dominant language
Rust
Stars
5.2k
Forks
312
Avg merge
11h 10m
Merged PRs (30d)
10

Description

I've been working on an expression evaluator in Godot-Rust, and I noticed if you call this function from Rust...
```gdscript
extends RefCounted

func foobar_func():
return Object
```
...and then call the `Debug` impl on its result value, it panics:
```
Result type: Ok("GDScriptNativeClass")
Result: Ok(The application panicked (crashed).
Message: Function call failed: call -- method not found.
Location: .../godot-core-0.5.5/src/builtin/variant/mod.rs:259
```
---
Here's some code that reproduces the issue:
```rust
let native_class = {
let mut script = GDScript::new_gd();
script.set_source_code(
r#"
extends RefCounted

func foobar_func():
return Object
"#,
);
script.reload().into_result().unwrap();
let mut obj = RefCounted::new_gd();
obj.set_script(&script);
obj.try_call("foobar_func", &[])
};

eprintln!(
"Result type: {:?}", // prints "GDScriptNativeClass"
native_class
.as_ref()
.map(|v| { v.to::>().get_class() })
);
eprintln!("Result: {:?}", native_class); // <-- PANIC HERE ------------------------------------------------------
```
---

According to the stack trace, the panic happens in this function:
```rust
#[cfg(since_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.4")))]
pub(crate) fn debug_string_variant(
obj: &Variant,
f: &mut std::fmt::Formatter<'_>,
ty: &str,
) -> std::fmt::Result {
sys::strict_assert_eq!(obj.get_type(), VariantType::OBJECT);

let id = obj
.object_id_unchecked()
.expect("Variant must be of type OBJECT");

if id.lookup_validity() {
let class = obj
.call("get_class", &[]) // <-- PANIC HERE ------------------------------------------------------
.try_to_relaxed::()
.expect("get_class() must be compatible with StringName");

let refcount = id.is_ref_counted().then(|| {
let count = obj
.call("get_reference_count", &[])
.try_to_relaxed::()
.expect("get_reference_count() must return integer");

count as usize
});

debug_string_parts(f, ty, id, class, refcount, None)
} else {
write!(f, "{ty} {{ freed obj }}")
}
}
```
I'm not familiar with the codebase, but it looks like it tries to call a method called `call` on it, which seems to be missing, so it panics with `Function call failed: call -- method not found.`.

---
`godot` crate version: v0.5.5

Contributor guide

Open the contributing guide

Research direction

Start in godot-core-0.5.5/src/builtin/variant/mod.rs at debug_string_variant, especially the get_class call shown in the stack trace. Run the provided GDScript and Rust reproducer, then verify that formatting a GDScriptNativeClass no longer panics and produces a valid Debug result.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.