Skip to content

Commit af53e74

Browse files
committed
Remove impl AsObjectArg<T> for &mut Gd<T>
`&mut obj` args can only be passed once, since &mut T: !Copy. This means that passing it to a Godot API works once, and then causes moved-out errors. This comes with a few issues: * It either needs the `&*` pattern or not, depending on the order of calls. Reordering breaks them. * It's inconsistent with `AsArg`, which is only implemented for `&T` in case of by-ref builtins. * Consuming `&mut T` should probably be allowed iff consuming `T` is allowed. That said, we'll need to check the ergonomic impact and see how arguments are being passed in practice.
1 parent 7bea565 commit af53e74

File tree

2 files changed

+14
-21
lines changed

2 files changed

+14
-21
lines changed

godot-core/src/obj/object_arg.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use std::ptr;
2525
/// The GDExtension API does not inform about nullability of its function parameters. It is up to you to verify that the arguments you pass
2626
/// are only null when this is allowed. Doing this wrong should be safe, but can lead to the function call failing.
2727
/// </div>
28-
2928
#[diagnostic::on_unimplemented(
3029
message = "Argument of type `{Self}` cannot be passed to an `impl AsObjectArg<{T}>` parameter",
3130
note = "If you pass by value, consider borrowing instead.",
@@ -80,22 +79,6 @@ where
8079
}
8180
}
8281

83-
impl<T, U> AsObjectArg<T> for &mut Gd<U>
84-
where
85-
T: GodotClass + Bounds<Declarer = bounds::DeclEngine>,
86-
U: Inherits<T>,
87-
{
88-
// Delegate to &Gd impl.
89-
90-
fn as_object_arg(&self) -> ObjectArg<T> {
91-
<&Gd<U>>::as_object_arg(&&**self)
92-
}
93-
94-
fn consume_arg(self) -> ObjectCow<T> {
95-
<&Gd<U>>::consume_arg(&*self)
96-
}
97-
}
98-
9982
impl<T, U> AsObjectArg<T> for Option<U>
10083
where
10184
T: GodotClass + Bounds<Declarer = bounds::DeclEngine>,

itest/rust/src/object_tests/object_arg_test.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ fn object_arg_borrowed() {
3939
fn object_arg_borrowed_mut() {
4040
with_objects(|mut manual, mut refc| {
4141
let db = ClassDb::singleton();
42-
let a = db.class_set_property(&mut manual, "name", &Variant::from("hello"));
43-
let b = db.class_set_property(&mut refc, "value", &Variant::from(-123));
42+
43+
let manual_ref = &mut manual;
44+
let refc_ref = &mut refc;
45+
46+
let a = db.class_set_property(&*manual_ref, "name", &Variant::from("hello"));
47+
let b = db.class_set_property(&*refc_ref, "value", &Variant::from(-123));
4448
(a, b)
4549
});
4650
}
@@ -69,10 +73,16 @@ fn object_arg_option_borrowed() {
6973

7074
#[itest]
7175
fn object_arg_option_borrowed_mut() {
76+
// If you have an Option<&mut Gd<T>>, you can use as_deref() to get Option<&Gd<T>>.
77+
7278
with_objects(|mut manual, mut refc| {
7379
let db = ClassDb::singleton();
74-
let a = db.class_set_property(Some(&mut manual), "name", &Variant::from("hello"));
75-
let b = db.class_set_property(Some(&mut refc), "value", &Variant::from(-123));
80+
81+
let manual_opt: Option<&mut Gd<Node>> = Some(&mut manual);
82+
let refc_opt: Option<&mut Gd<RefcPayload>> = Some(&mut refc);
83+
84+
let a = db.class_set_property(manual_opt.as_deref(), "name", &Variant::from("hello"));
85+
let b = db.class_set_property(refc_opt.as_deref(), "value", &Variant::from(-123));
7686
(a, b)
7787
});
7888
}

0 commit comments

Comments
 (0)