Repository: bitshifter/glam-rs
Pull request #486 (2024-03-06 15:04:41)

Make all tests pass with panic=abort
The panic="unwind" cfg has been stable since rustc 1.60.


Patch:
diff --git a/benches/vec3.rs b/benches/vec3.rs
index 78d5d63..39197a3 100644
--- a/benches/vec3.rs
+++ b/benches/vec3.rs
@@ -79,6 +79,18 @@ bench_func!(
     from => random_vec3
 );
 
+#[inline]
+fn vec3_normalize_or(v: Vec3) -> Vec3 {
+    v.normalize_or(Vec3::X)
+}
+
+bench_func!(
+    vec3_normalize_or_bench,
+    "vec3 normalize_or",
+    op => vec3_normalize_or,
+    from => random_vec3
+);
+
 #[inline]
 fn vec3_normalize_or_zero(v: Vec3) -> Vec3 {
     v.normalize_or_zero()
@@ -154,6 +166,7 @@ criterion_group!(
     vec3_mul_vec3,
     vec3_angle_between,
     vec3_normalize_bench,
+    vec3_normalize_or_bench,
     vec3_normalize_or_zero_bench,
     vec3_any_orthogonal_vector_bench,
     vec3_any_orthonormal_vector_bench,
diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera
index ee8b29b..d39e0e9 100644
--- a/codegen/templates/vec.rs.tera
+++ b/codegen/templates/vec.rs.tera
@@ -1350,23 +1350,36 @@ impl {{ self_t }} {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs
index 7a7652c..dfe0105 100644
--- a/src/f32/coresimd/vec3a.rs
+++ b/src/f32/coresimd/vec3a.rs
@@ -493,23 +493,36 @@ impl Vec3A {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs
index 15b0fb2..aed9d5a 100644
--- a/src/f32/coresimd/vec4.rs
+++ b/src/f32/coresimd/vec4.rs
@@ -465,23 +465,36 @@ impl Vec4 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/scalar/vec3a.rs b/src/f32/scalar/vec3a.rs
index a163477..0dac019 100644
--- a/src/f32/scalar/vec3a.rs
+++ b/src/f32/scalar/vec3a.rs
@@ -514,23 +514,36 @@ impl Vec3A {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/scalar/vec4.rs b/src/f32/scalar/vec4.rs
index 76b20c8..cb2c202 100644
--- a/src/f32/scalar/vec4.rs
+++ b/src/f32/scalar/vec4.rs
@@ -548,23 +548,36 @@ impl Vec4 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs
index 56e274f..2a0a8a1 100644
--- a/src/f32/sse2/vec3a.rs
+++ b/src/f32/sse2/vec3a.rs
@@ -541,23 +541,36 @@ impl Vec3A {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs
index 2e37268..1b2e3ab 100644
--- a/src/f32/sse2/vec4.rs
+++ b/src/f32/sse2/vec4.rs
@@ -514,23 +514,36 @@ impl Vec4 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/vec2.rs b/src/f32/vec2.rs
index 7b01a2a..bd57c42 100644
--- a/src/f32/vec2.rs
+++ b/src/f32/vec2.rs
@@ -455,23 +455,36 @@ impl Vec2 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/vec3.rs b/src/f32/vec3.rs
index bf11a43..8f0c202 100644
--- a/src/f32/vec3.rs
+++ b/src/f32/vec3.rs
@@ -505,23 +505,36 @@ impl Vec3 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs
index 3709a89..352a9ca 100644
--- a/src/f32/wasm32/vec3a.rs
+++ b/src/f32/wasm32/vec3a.rs
@@ -512,23 +512,36 @@ impl Vec3A {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs
index c0574b2..c728cc3 100644
--- a/src/f32/wasm32/vec4.rs
+++ b/src/f32/wasm32/vec4.rs
@@ -492,23 +492,36 @@ impl Vec4 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f64/dvec2.rs b/src/f64/dvec2.rs
index 72b0852..98f92f1 100644
--- a/src/f64/dvec2.rs
+++ b/src/f64/dvec2.rs
@@ -455,23 +455,36 @@ impl DVec2 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f64/dvec3.rs b/src/f64/dvec3.rs
index 925feeb..d121395 100644
--- a/src/f64/dvec3.rs
+++ b/src/f64/dvec3.rs
@@ -505,23 +505,36 @@ impl DVec3 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.
diff --git a/src/f64/dvec4.rs b/src/f64/dvec4.rs
index 356e9db..ea878ba 100644
--- a/src/f64/dvec4.rs
+++ b/src/f64/dvec4.rs
@@ -536,23 +536,36 @@ impl DVec4 {
         }
     }
 
-    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    /// Returns `self` normalized to length 1.0 if possible, else returns a
+    /// fallback value.
     ///
     /// In particular, if the input is zero (or very close to zero), or non-finite,
-    /// the result of this operation will be zero.
+    /// the result of this operation will be the fallback value.
     ///
     /// See also [`Self::try_normalize()`].
     #[inline]
     #[must_use]
-    pub fn normalize_or_zero(self) -> Self {
+    pub fn normalize_or(self, fallback: Self) -> Self {
         let rcp = self.length_recip();
         if rcp.is_finite() && rcp > 0.0 {
             self * rcp
         } else {
-            Self::ZERO
+            fallback
         }
     }
 
+    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
+    ///
+    /// In particular, if the input is zero (or very close to zero), or non-finite,
+    /// the result of this operation will be zero.
+    ///
+    /// See also [`Self::try_normalize()`].
+    #[inline]
+    #[must_use]
+    pub fn normalize_or_zero(self) -> Self {
+        self.normalize_or(Self::ZERO)
+    }
+
     /// Returns whether `self` is length `1.0` or not.
     ///
     /// Uses a precision threshold of approximately `1e-4`.


Test patch:
diff --git a/tests/support/macros.rs b/tests/support/macros.rs
index 52f7a64..135e863 100644
--- a/tests/support/macros.rs
+++ b/tests/support/macros.rs
@@ -12,7 +12,7 @@ macro_rules! glam_test {
 #[macro_export]
 macro_rules! should_panic {
     ($block:block) => {{
-        #[cfg(all(feature = "std", not(target_arch = "wasm32")))]
+        #[cfg(all(feature = "std", panic = "unwind"))]
         assert!(std::panic::catch_unwind(|| $block).is_err());
     }};
 }
@@ -137,6 +137,29 @@ macro_rules! impl_vec_float_normalize_tests {
             assert_eq!(from_x_y(MAX, MAX).try_normalize(), None);
         });
 
+        glam_test!(test_normalize_or, {
+            assert_eq!(
+                from_x_y(-42.0, 0.0).normalize_or($vec::Y),
+                from_x_y(-1.0, 0.0)
+            );
+            assert_eq!(
+                from_x_y(MAX.sqrt(), 0.0).normalize_or($vec::Y),
+                from_x_y(1.0, 0.0)
+            );
+
+            // We expect `normalize_or` to return the fallback value when inputs are very small:
+            assert_eq!(from_x_y(0.0, 0.0).normalize_or($vec::Y), $vec::Y);
+            assert_eq!(from_x_y(MIN_POSITIVE, 0.0).normalize_or($vec::Y), $vec::Y);
+
+            // We expect `normalize` to return zero when inputs are non-finite:
+            assert_eq!(from_x_y(INFINITY, 0.0).normalize_or($vec::Y), $vec::Y);
+            assert_eq!(from_x_y(NAN, 0.0).normalize_or($vec::Y), $vec::Y);
+
+            // We expect `normalize` to return zero when inputs are very large:
+            assert_eq!(from_x_y(MAX, 0.0).normalize_or($vec::Y), $vec::Y);
+            assert_eq!(from_x_y(MAX, MAX).normalize_or($vec::Y), $vec::Y);
+        });
+
         glam_test!(test_normalize_or_zero, {
             assert_eq!(
                 from_x_y(-42.0, 0.0).normalize_or_zero(),