Skip to content

Commit 1690b28

Browse files
authored
Fixing Curve trait not being object safe. (#14939)
# Objective - `Curve<T>` was meant to be object safe, but one of the latest commits made it not object safe. - When trying to use `Curve<T>` as `&dyn Curve<T>` this compile error is raised: ``` error[E0038]: the trait `curve::Curve` cannot be made into an object --> crates/bevy_math/src/curve/mod.rs:1025:20 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> crates/bevy_math/src/curve/mod.rs:60:8 | 23 | pub trait Curve<T> { | ----- this trait cannot be made into an object... ... 60 | fn sample_iter(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = Option<T>> { | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `sample_iter` references an `impl Trait` type in its return type | | | ...because method `sample_iter` has generic type parameters ... ``` ## Solution - Making `Curve<T>` object safe again by adding `Self: Sized` to newly added methods. ## Testing - Added new test that ensures the `Curve<T>` trait can be made into an objet.
1 parent e320fa0 commit 1690b28

File tree

1 file changed

+24
-6
lines changed
  • crates/bevy_math/src/curve

1 file changed

+24
-6
lines changed

crates/bevy_math/src/curve/mod.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ pub trait Curve<T> {
5757
/// The samples are returned in the same order as the parameter values `t_n` were provided and
5858
/// will include all results. This leaves the responsibility for things like filtering and
5959
/// sorting to the user for maximum flexibility.
60-
fn sample_iter(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = Option<T>> {
60+
fn sample_iter(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = Option<T>>
61+
where
62+
Self: Sized,
63+
{
6164
iter.into_iter().map(|t| self.sample(t))
6265
}
6366

@@ -72,10 +75,10 @@ pub trait Curve<T> {
7275
/// The samples are returned in the same order as the parameter values `t_n` were provided and
7376
/// will include all results. This leaves the responsibility for things like filtering and
7477
/// sorting to the user for maximum flexibility.
75-
fn sample_iter_unchecked(
76-
&self,
77-
iter: impl IntoIterator<Item = f32>,
78-
) -> impl Iterator<Item = T> {
78+
fn sample_iter_unchecked(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = T>
79+
where
80+
Self: Sized,
81+
{
7982
iter.into_iter().map(|t| self.sample_unchecked(t))
8083
}
8184

@@ -85,7 +88,10 @@ pub trait Curve<T> {
8588
/// The samples are returned in the same order as the parameter values `t_n` were provided and
8689
/// will include all results. This leaves the responsibility for things like filtering and
8790
/// sorting to the user for maximum flexibility.
88-
fn sample_iter_clamped(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = T> {
91+
fn sample_iter_clamped(&self, iter: impl IntoIterator<Item = f32>) -> impl Iterator<Item = T>
92+
where
93+
Self: Sized,
94+
{
8995
iter.into_iter().map(|t| self.sample_clamped(t))
9096
}
9197

@@ -760,6 +766,9 @@ where
760766
/// must be left-finite.
761767
///
762768
/// Curves of this type are produced by [`Curve::chain`].
769+
#[derive(Clone, Debug)]
770+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
771+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
763772
pub struct ChainCurve<T, C, D> {
764773
first: C,
765774
second: D,
@@ -1013,6 +1022,15 @@ mod tests {
10131022
use approx::{assert_abs_diff_eq, AbsDiffEq};
10141023
use std::f32::consts::TAU;
10151024

1025+
#[test]
1026+
fn curve_can_be_made_into_an_object() {
1027+
let curve = constant_curve(Interval::UNIT, 42.0);
1028+
let curve: &dyn Curve<f64> = &curve;
1029+
1030+
assert_eq!(curve.sample(1.0), Some(42.0));
1031+
assert_eq!(curve.sample(2.0), None);
1032+
}
1033+
10161034
#[test]
10171035
fn constant_curves() {
10181036
let curve = constant_curve(Interval::EVERYWHERE, 5.0);

0 commit comments

Comments
 (0)