Skip to content

Commit d8069a0

Browse files
authored
Merge pull request #1321 from godot-rust/qol/object-arg-lifetime
FFI: make `AsArg` internals safer to use
2 parents b2243fb + 51e2e17 commit d8069a0

File tree

7 files changed

+148
-155
lines changed

7 files changed

+148
-155
lines changed

godot-core/src/meta/args/as_arg.rs

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::ffi::CStr;
1010
use crate::builtin::{GString, NodePath, StringName, Variant};
1111
use crate::meta::sealed::Sealed;
1212
use crate::meta::traits::{GodotFfiVariant, GodotNullableFfi};
13-
use crate::meta::{CowArg, GodotType, ObjectArg, ToGodot};
13+
use crate::meta::{CowArg, FfiArg, GodotType, ObjectArg, ToGodot};
1414
use crate::obj::{bounds, Bounds, DynGd, Gd, GodotClass, Inherits};
1515

1616
/// Implicit conversions for arguments passed to Godot APIs.
@@ -97,13 +97,14 @@ where
9797

9898
/// FFI-optimized argument conversion that may use `FfiObject` when beneficial.
9999
///
100-
/// Defaults to calling `into_arg()`, which always works, but might be an `Owned` for a conservative approach (e.g. object upcast).
100+
/// Defaults to calling `into_arg()` and wrapping in `FfiArg::Cow()`, which always works, but might be an `Owned` for a conservative
101+
/// approach (e.g. object upcast).
101102
#[doc(hidden)]
102-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, T>
103+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, T>
103104
where
104105
Self: 'arg,
105106
{
106-
self.into_arg()
107+
FfiArg::Cow(self.into_arg())
107108
}
108109
}
109110

@@ -157,13 +158,12 @@ where
157158
}
158159
}
159160

160-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, Gd<Base>>
161+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, Gd<Base>>
161162
where
162163
Self: 'arg,
163164
{
164-
// SAFETY: ObjectArg exists only during FFI call.
165-
let arg = unsafe { ObjectArg::from_gd(self) };
166-
CowArg::FfiObject(arg)
165+
let arg = ObjectArg::from_gd(self);
166+
FfiArg::FfiObject(arg)
167167
}
168168
}
169169

@@ -190,13 +190,12 @@ where
190190
}
191191
}
192192

193-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, DynGd<Base, D>>
193+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, DynGd<Base, D>>
194194
where
195195
Self: 'arg,
196196
{
197-
// SAFETY: ObjectArg exists only during FFI call.
198-
let arg = unsafe { ObjectArg::from_gd(self) };
199-
CowArg::FfiObject(arg)
197+
let arg = ObjectArg::from_gd(self);
198+
FfiArg::FfiObject(arg)
200199
}
201200
}
202201

@@ -215,7 +214,7 @@ where
215214
AsArg::into_arg(gd_ref)
216215
}
217216

218-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, Gd<Base>>
217+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, Gd<Base>>
219218
where
220219
Self: 'arg,
221220
{
@@ -244,13 +243,12 @@ where
244243
}
245244
}
246245

247-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, Option<Gd<Base>>>
246+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, Option<Gd<Base>>>
248247
where
249248
Self: 'arg,
250249
{
251-
// SAFETY: ObjectArg exists only during FFI call.
252-
let arg = unsafe { ObjectArg::from_option_gd(self) };
253-
CowArg::FfiObject(arg)
250+
let arg = ObjectArg::from_option_gd(self);
251+
FfiArg::FfiObject(arg)
254252
}
255253
}
256254

@@ -268,13 +266,12 @@ where
268266
CowArg::Owned(Some(self.clone().upcast::<Base>()))
269267
}
270268

271-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, Option<Gd<Base>>>
269+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, Option<Gd<Base>>>
272270
where
273271
Self: 'arg,
274272
{
275-
// SAFETY: ObjectArg exists only during FFI call.
276-
let arg = unsafe { ObjectArg::from_gd(self) };
277-
CowArg::FfiObject(arg)
273+
let arg = ObjectArg::from_gd(self);
274+
FfiArg::FfiObject(arg)
278275
}
279276
}
280277

@@ -293,7 +290,7 @@ where
293290
AsArg::into_arg(gd_ref)
294291
}
295292

296-
fn into_ffi_arg<'arg>(self) -> CowArg<'arg, Option<Gd<Base>>>
293+
fn into_ffi_arg<'arg>(self) -> FfiArg<'arg, Option<Gd<Base>>>
297294
where
298295
Self: 'arg,
299296
{
@@ -614,7 +611,7 @@ impl ArgPassing for ByObject {
614611
type Output<'r, T: 'r> = &'r T;
615612

616613
type FfiOutput<'f, T>
617-
= ObjectArg
614+
= ObjectArg<'f>
618615
where
619616
T: GodotType + 'f;
620617

@@ -627,13 +624,13 @@ impl ArgPassing for ByObject {
627624
value.to_godot().clone()
628625
}
629626

630-
fn ref_to_ffi<T>(value: &T) -> ObjectArg
627+
fn ref_to_ffi<T>(value: &T) -> ObjectArg<'_>
631628
where
632629
T: ToGodot<Pass = Self>,
633630
T::Via: GodotType,
634631
{
635632
let obj_ref: &T::Via = value.to_godot(); // implements GodotType.
636-
unsafe { obj_ref.as_object_arg() }
633+
obj_ref.as_object_arg()
637634
}
638635
}
639636

0 commit comments

Comments
 (0)