Skip to content

Commit cf0a33a

Browse files
committed
#[func] argument passing now uses relaxed conversions
This is consistent with passing in GDScript, as well as varcalls in GDExtension (passing variants instead of pointers/scalars). Should avoid subtle discrepancies that currently occur depending on whether a GDScript value is typed or not.
1 parent 01fc5d4 commit cf0a33a

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

godot-core/src/builtin/variant/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ impl Variant {
114114
try_from_variant_relaxed(self)
115115
}
116116

117+
/// Helper function for relaxed variant conversion with panic on failure.
118+
/// Similar to [`to()`](Self::to) but uses relaxed conversion rules.
119+
pub(crate) fn to_relaxed_or_panic<T, F>(&self, context: F) -> T
120+
where
121+
T: FromGodot,
122+
F: FnOnce() -> String,
123+
{
124+
self.try_to_relaxed::<T>()
125+
.unwrap_or_else(|err| panic!("{}: {err}", context()))
126+
}
127+
117128
/// Checks whether the variant is empty (`null` value in GDScript).
118129
///
119130
/// See also [`get_type()`][Self::get_type].

godot-core/src/meta/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ pub use uniform_object_deref::UniformObjectDeref;
6767

6868
pub(crate) use array_type_info::ArrayTypeInfo;
6969
pub(crate) use traits::{
70-
element_godot_type_name, ffi_variant_type, element_variant_type, GodotFfiVariant, GodotNullableFfi,
70+
element_godot_type_name, element_variant_type, ffi_variant_type, GodotFfiVariant,
71+
GodotNullableFfi,
7172
};
7273

7374
use crate::registry::method::MethodParamOrReturnInfo;

godot-core/src/meta/param_tuple/impls.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,13 @@ macro_rules! unsafe_impl_param_tuple {
9393
let mut iter = array.iter();
9494
(
9595
$(
96-
<$P>::from_variant(
97-
iter.next().unwrap_or_else(|| panic!("ParamTuple: {} access out-of-bounds (len {})", stringify!($p), array.len()))
98-
),
96+
{
97+
let variant = iter.next().unwrap_or_else(
98+
|| panic!("ParamTuple: {} access out-of-bounds (len {})", stringify!($p), array.len()));
99+
100+
variant.to_relaxed_or_panic(
101+
|| format!("ParamTuple: failed to convert parameter {}", stringify!($p)))
102+
},
99103
)*
100104
)
101105
}
@@ -222,7 +226,8 @@ pub(super) unsafe fn varcall_arg<P: FromGodot>(
222226
// SAFETY: It is safe to dereference `args_ptr` at `N` as a `Variant`.
223227
let variant_ref = unsafe { Variant::borrow_var_sys(arg) };
224228

225-
P::try_from_variant(variant_ref)
229+
variant_ref
230+
.try_to_relaxed::<P>()
226231
.map_err(|err| CallError::failed_param_conversion::<P>(call_ctx, param_index, err))
227232
}
228233

0 commit comments

Comments
 (0)