Repository: bitshifter/glam-rs
Pull request #585 (2024-11-10 22:07:34)

Use macro for implementations of `ops` traits on references
- Reduce bloat in the template by using a macro for the reference based ops from #549.
- Makes it easier to add these implementations for other types/ops too :) #335 

I added a naive snake_case filter to tera to avoid needing to specify the method name at every macro invocation.

The macros itself is.. pretty gross, as expected.

There is only a slight aesthetic change to the generated code. `Self` to `{{ self_t }}` for the `XXXAssign` ops.

bitshifter: Wow, you've been busy! I will get around to reviewing all of these sometime this week hopefully

Patch:
diff --git a/Cargo.toml b/Cargo.toml
index d3cb2ef..86272e2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -123,6 +123,7 @@ harness = false
 [workspace]
 members = [
     "codegen",
+    "swizzlegen",
     "test_no_std",
 ]
 
diff --git a/codegen/src/main.rs b/codegen/src/main.rs
index 854ab96..048808e 100644
--- a/codegen/src/main.rs
+++ b/codegen/src/main.rs
@@ -4,6 +4,7 @@ use anyhow::{bail, Context};
 use clap::{arg, command};
 use rustfmt_wrapper::rustfmt;
 use std::path::Path;
+use tera::{from_value, to_value, Value};
 
 use outputs::build_output_pairs;
 
@@ -60,7 +61,28 @@ fn main() -> anyhow::Result<()> {
     } else {
         None
     };
-    let tera = tera::Tera::new("templates/**/*.rs.tera").context("tera parsing error(s)")?;
+    let mut tera = tera::Tera::new("templates/**/*.rs.tera").context("tera parsing error(s)")?;
+    tera.register_filter(
+        "snake_case",
+        |value: &Value, _: &_| -> tera::Result<Value> {
+            let input = from_value::<String>(value.clone())?;
+            let mut iter = input.chars();
+
+            let mut string = String::new();
+
+            if let Some(first) = iter.next() {
+                string.push(first.to_ascii_lowercase());
+
+                for char in iter {
+                    if char.is_uppercase() {
+                        string.push('_');
+                    }
+                    string.push(char.to_ascii_lowercase());
+                }
+            }
+            tera::Result::Ok(to_value(string)?)
+        },
+    );
 
     let repo = git2::Repository::open(GLAM_ROOT).context("failed to open git repo")?;
     let workdir = repo.workdir().unwrap();
diff --git a/codegen/templates/macros.rs.tera b/codegen/templates/macros.rs.tera
index 475ec78..83b6c6b 100644
--- a/codegen/templates/macros.rs.tera
+++ b/codegen/templates/macros.rs.tera
@@ -71,3 +71,36 @@
         }
     }
 {% endmacro impl_mat4_minor %}
+
+
+{% macro impl_op_ref_inner(op, self_t, rhs_t, output_t, self, self_ref, rhs_ref) %}
+{% set method = op | snake_case %}
+{% if rhs_ref and rhs_t %}
+    {% set rhs = "&" ~ rhs_t %}
+{% elif rhs_t %}
+    {% set rhs = rhs_t %}
+{% endif %}
+
+impl {{ op }}{% if rhs_t %}<{{ rhs }}>{% endif %} for {% if self_ref %}&{% endif %}{{ self_t }} {
+    {% if output_t %}
+    type Output = {{ output_t }};
+    {% endif -%}
+    #[inline]
+    fn {{ method }}({{ self }}{% if rhs_t %}, rhs: {{ rhs }}{% endif %}){% if output_t %} -> {{ output_t }}{% endif %}{ 
+        {% if self_ref %} (*self) {% else %} self {% endif %}.{{method}}
+        ({% if rhs_ref %} *rhs {% elif rhs_t %} rhs {% endif %})
+    }
+}
+{% endmacro impl_op_ref_inner %}
+
+{% macro impl_op_ref(op, self_t, rhs_t=false, output_t=false, self="self") %}
+{%if rhs_t %}
+    {{ self::impl_op_ref_inner(op=op, self_t=self_t, rhs_t=rhs_t, output_t=output_t, self=self, self_ref=false, rhs_ref=true) }}
+    {%if output_t %}
+        {{ self::impl_op_ref_inner(op=op, self_t=self_t, rhs_t=rhs_t, output_t=output_t, self=self, self_ref=true, rhs_ref=true) }}
+    {% endif %}
+{% endif %}
+{%if output_t %}
+    {{ self::impl_op_ref_inner(op=op, self_t=self_t, rhs_t=rhs_t, output_t=output_t, self=self, self_ref=true, rhs_ref=false) }}
+{% endif %}
+{% endmacro impl_op_ref %}
diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera
index 7859070..0c8fa86 100644
--- a/codegen/templates/vec.rs.tera
+++ b/codegen/templates/vec.rs.tera
@@ -2695,29 +2695,7 @@ impl Div<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl Div<&{{ self_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.div(*rhs)
-    }
-}
-
-impl Div<&{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).div(*rhs)
-    }
-}
-
-impl Div<{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).div(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Div", self_t=self_t, rhs_t=self_t, output_t=self_t) }}
 
 impl DivAssign<{{ self_t }}> for {{ self_t }} {
     #[inline]
@@ -2740,12 +2718,7 @@ impl DivAssign<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl DivAssign<&Self> for {{ self_t }} {
-    #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
-        self.div_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="DivAssign", self_t=self_t, rhs_t=self_t, self="&mut self") }}
 
 impl Div<{{ scalar_t }}> for {{ self_t }} {
     type Output = Self;
@@ -2771,29 +2744,7 @@ impl Div<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl Div<&{{ scalar_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        self.div(*rhs)
-    }
-}
-
-impl Div<&{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        (*self).div(*rhs)
-    }
-}
-
-impl Div<{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: {{ scalar_t }}) -> {{ self_t }} {
-        (*self).div(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Div", self_t=self_t, rhs_t=scalar_t, output_t=self_t) }}
 
 impl DivAssign<{{ scalar_t }}> for {{ self_t }} {
     #[inline]
@@ -2816,12 +2767,7 @@ impl DivAssign<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl DivAssign<&{{ scalar_t }}> for {{ self_t }} {
-    #[inline]
-    fn div_assign(&mut self, rhs: &{{ scalar_t }}) {
-        self.div_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="DivAssign", self_t=self_t, rhs_t=scalar_t, self="&mut self") }}
 
 impl Div<{{ self_t }}> for {{ scalar_t }} {
     type Output = {{ self_t }};
@@ -2847,29 +2793,7 @@ impl Div<{{ self_t }}> for {{ scalar_t }} {
     }
 }
 
-impl Div<&{{ self_t }}> for {{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.div(*rhs)
-    }
-}
-
-impl Div<&{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).div(*rhs)
-    }
-}
-
-impl Div<{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn div(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).div(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Div", self_t=scalar_t, rhs_t=self_t, output_t=self_t) }}
 
 impl Mul<{{ self_t }}> for {{ self_t }} {
     type Output = Self;
@@ -2895,29 +2819,7 @@ impl Mul<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl Mul<&{{ self_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.mul(*rhs)
-    }
-}
-
-impl Mul<&{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).mul(*rhs)
-    }
-}
-
-impl Mul<{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).mul(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Mul", self_t=self_t, rhs_t=self_t, output_t=self_t) }}
 
 impl MulAssign<{{ self_t }}> for {{ self_t }} {
     #[inline]
@@ -2940,12 +2842,7 @@ impl MulAssign<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl MulAssign<&Self> for {{ self_t }} {
-    #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
-        self.mul_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="MulAssign", self_t=self_t, rhs_t=self_t, self="&mut self") }}
 
 impl Mul<{{ scalar_t }}> for {{ self_t }} {
     type Output = Self;
@@ -2971,29 +2868,7 @@ impl Mul<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl Mul<&{{ scalar_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        self.mul(*rhs)
-    }
-}
-
-impl Mul<&{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        (*self).mul(*rhs)
-    }
-}
-
-impl Mul<{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: {{ scalar_t }}) -> {{ self_t }} {
-        (*self).mul(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Mul", self_t=self_t, rhs_t=scalar_t, output_t=self_t) }}
 
 impl MulAssign<{{ scalar_t }}> for {{ self_t }} {
     #[inline]
@@ -3016,12 +2891,7 @@ impl MulAssign<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl MulAssign<&{{ scalar_t }}> for {{ self_t }} {
-    #[inline]
-    fn mul_assign(&mut self, rhs: &{{ scalar_t }}) {
-        self.mul_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="MulAssign", self_t=self_t, rhs_t=scalar_t, self="&mut self") }}
 
 impl Mul<{{ self_t }}> for {{ scalar_t }} {
     type Output = {{ self_t }};
@@ -3047,29 +2917,7 @@ impl Mul<{{ self_t }}> for {{ scalar_t }} {
     }
 }
 
-impl Mul<&{{ self_t }}> for {{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.mul(*rhs)
-    }
-}
-
-impl Mul<&{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).mul(*rhs)
-    }
-}
-
-impl Mul<{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn mul(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).mul(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Mul", self_t=scalar_t, rhs_t=self_t, output_t=self_t) }}
 
 impl Add<{{ self_t }}> for {{ self_t }} {
     type Output = Self;
@@ -3095,29 +2943,7 @@ impl Add<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl Add<&{{ self_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.add(*rhs)
-    }
-}
-
-impl Add<&{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).add(*rhs)
-    }
-}
-
-impl Add<{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).add(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Add", self_t=self_t, rhs_t=self_t, output_t=self_t) }}
 
 impl AddAssign<{{ self_t }}> for {{ self_t }} {
     #[inline]
@@ -3140,12 +2966,7 @@ impl AddAssign<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl AddAssign<&Self> for {{ self_t }} {
-    #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
-        self.add_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="AddAssign", self_t=self_t, rhs_t=self_t, self="&mut self") }}
 
 impl Add<{{ scalar_t }}> for {{ self_t }} {
     type Output = Self;
@@ -3171,29 +2992,7 @@ impl Add<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl Add<&{{ scalar_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        self.add(*rhs)
-    }
-}
-
-impl Add<&{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        (*self).add(*rhs)
-    }
-}
-
-impl Add<{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: {{ scalar_t }}) -> {{ self_t }} {
-        (*self).add(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Add", self_t=self_t, rhs_t=scalar_t, output_t=self_t) }}
 
 impl AddAssign<{{ scalar_t }}> for {{ self_t }} {
     #[inline]
@@ -3216,12 +3015,7 @@ impl AddAssign<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl AddAssign<&{{ scalar_t }}> for {{ self_t }} {
-    #[inline]
-    fn add_assign(&mut self, rhs: &{{ scalar_t }}) {
-        self.add_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="AddAssign", self_t=self_t, rhs_t=scalar_t, self="&mut self") }}
 
 impl Add<{{ self_t }}> for {{ scalar_t }} {
     type Output = {{ self_t }};
@@ -3247,29 +3041,7 @@ impl Add<{{ self_t }}> for {{ scalar_t }} {
     }
 }
 
-impl Add<&{{ self_t }}> for {{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.add(*rhs)
-    }
-}
-
-impl Add<&{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).add(*rhs)
-    }
-}
-
-impl Add<{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn add(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).add(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Add", self_t=scalar_t, rhs_t=self_t, output_t=self_t) }}
 
 impl Sub<{{ self_t }}> for {{ self_t }} {
     type Output = Self;
@@ -3295,29 +3067,7 @@ impl Sub<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl Sub<&{{ self_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.sub(*rhs)
-    }
-}
-
-impl Sub<&{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).sub(*rhs)
-    }
-}
-
-impl Sub<{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).sub(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Sub", self_t=self_t, rhs_t=self_t, output_t=self_t) }}
 
 impl SubAssign<{{ self_t }}> for {{ self_t }} {
     #[inline]
@@ -3340,12 +3090,7 @@ impl SubAssign<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl SubAssign<&Self> for {{ self_t }} {
-    #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
-        self.sub_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="SubAssign", self_t=self_t, rhs_t=self_t, self="&mut self") }}
 
 impl Sub<{{ scalar_t }}> for {{ self_t }} {
     type Output = Self;
@@ -3371,29 +3116,7 @@ impl Sub<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl Sub<&{{ scalar_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        self.sub(*rhs)
-    }
-}
-
-impl Sub<&{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        (*self).sub(*rhs)
-    }
-}
-
-impl Sub<{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: {{ scalar_t }}) -> {{ self_t }} {
-        (*self).sub(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Sub", self_t=self_t, rhs_t=scalar_t, output_t=self_t) }}
 
 impl SubAssign<{{ scalar_t }}> for {{ self_t }} {
     #[inline]
@@ -3416,12 +3139,7 @@ impl SubAssign<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl SubAssign<&{{ scalar_t }}> for {{ self_t }} {
-    #[inline]
-    fn sub_assign(&mut self, rhs: &{{ scalar_t }}) {
-        self.sub_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="SubAssign", self_t=self_t, rhs_t=scalar_t, self="&mut self") }}
 
 impl Sub<{{ self_t }}> for {{ scalar_t }} {
     type Output = {{ self_t }};
@@ -3447,29 +3165,7 @@ impl Sub<{{ self_t }}> for {{ scalar_t }} {
     }
 }
 
-impl Sub<&{{ self_t }}> for {{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.sub(*rhs)
-    }
-}
-
-impl Sub<&{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).sub(*rhs)
-    }
-}
-
-impl Sub<{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn sub(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).sub(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Sub", self_t=scalar_t, rhs_t=self_t, output_t=self_t) }}
 
 impl Rem<{{ self_t }}> for {{ self_t }} {
     type Output = Self;
@@ -3502,29 +3198,7 @@ impl Rem<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl Rem<&{{ self_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.rem(*rhs)
-    }
-}
-
-impl Rem<&{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).rem(*rhs)
-    }
-}
-
-impl Rem<{{ self_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).rem(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Rem", self_t=self_t, rhs_t=self_t, output_t=self_t) }}
 
 impl RemAssign<{{ self_t }}> for {{ self_t }} {
     #[inline]
@@ -3541,12 +3215,7 @@ impl RemAssign<{{ self_t }}> for {{ self_t }} {
     }
 }
 
-impl RemAssign<&Self> for {{ self_t }} {
-    #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
-        self.rem_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="RemAssign", self_t=self_t, rhs_t=self_t, self="&mut self") }}
 
 impl Rem<{{ scalar_t }}> for {{ self_t }} {
     type Output = Self;
@@ -3564,29 +3233,7 @@ impl Rem<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl Rem<&{{ scalar_t }}> for {{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        self.rem(*rhs)
-    }
-}
-
-impl Rem<&{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: &{{ scalar_t }}) -> {{ self_t }} {
-        (*self).rem(*rhs)
-    }
-}
-
-impl Rem<{{ scalar_t }}> for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: {{ scalar_t }}) -> {{ self_t }} {
-        (*self).rem(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Rem", self_t=self_t, rhs_t=scalar_t, output_t=self_t) }}
 
 impl RemAssign<{{ scalar_t }}> for {{ self_t }} {
     #[inline]
@@ -3603,12 +3250,7 @@ impl RemAssign<{{ scalar_t }}> for {{ self_t }} {
     }
 }
 
-impl RemAssign<&{{ scalar_t }}> for {{ self_t }} {
-    #[inline]
-    fn rem_assign(&mut self, rhs: &{{ scalar_t }}) {
-        self.rem_assign(*rhs)
-    }
-}
+{{ macros::impl_op_ref(op="RemAssign", self_t=self_t, rhs_t=scalar_t, self="&mut self") }}
 
 impl Rem<{{ self_t }}> for {{ scalar_t }} {
     type Output = {{ self_t }};
@@ -3626,29 +3268,7 @@ impl Rem<{{ self_t }}> for {{ scalar_t }} {
     }
 }
 
-impl Rem<&{{ self_t }}> for {{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        self.rem(*rhs)
-    }
-}
-
-impl Rem<&{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: &{{ self_t }}) -> {{ self_t }} {
-        (*self).rem(*rhs)
-    }
-}
-
-impl Rem<{{ self_t }}> for &{{ scalar_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn rem(self, rhs: {{ self_t }}) -> {{ self_t }} {
-        (*self).rem(rhs)
-    }
-}
+{{ macros::impl_op_ref(op="Rem", self_t=scalar_t, rhs_t=self_t, output_t=self_t) }}
 
 #[cfg(not(target_arch = "spirv"))]
 impl AsRef<[{{ scalar_t }}; {{ dim }}]> for {{ self_t }} {
@@ -3731,13 +3351,7 @@ impl Neg for {{ self_t }} {
     }
 }
 
-impl Neg for &{{ self_t }} {
-    type Output = {{ self_t }};
-    #[inline]
-    fn neg(self) -> {{ self_t }} {
-        (*self).neg()
-    }
-}
+{{ macros::impl_op_ref(op="Neg", self_t=self_t, output_t=self_t) }}
 {% endif %}
 
 {% if not is_float %}
diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs
index 3601af8..d0be62d 100644
--- a/src/f32/coresimd/vec3a.rs
+++ b/src/f32/coresimd/vec3a.rs
@@ -1056,9 +1056,9 @@ impl DivAssign<Vec3A> for Vec3A {
     }
 }
 
-impl DivAssign<&Self> for Vec3A {
+impl DivAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec3A) {
         self.div_assign(*rhs)
     }
 }
@@ -1180,9 +1180,9 @@ impl MulAssign<Vec3A> for Vec3A {
     }
 }
 
-impl MulAssign<&Self> for Vec3A {
+impl MulAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec3A) {
         self.mul_assign(*rhs)
     }
 }
@@ -1304,9 +1304,9 @@ impl AddAssign<Vec3A> for Vec3A {
     }
 }
 
-impl AddAssign<&Self> for Vec3A {
+impl AddAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec3A) {
         self.add_assign(*rhs)
     }
 }
@@ -1428,9 +1428,9 @@ impl SubAssign<Vec3A> for Vec3A {
     }
 }
 
-impl SubAssign<&Self> for Vec3A {
+impl SubAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec3A) {
         self.sub_assign(*rhs)
     }
 }
@@ -1552,9 +1552,9 @@ impl RemAssign<Vec3A> for Vec3A {
     }
 }
 
-impl RemAssign<&Self> for Vec3A {
+impl RemAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec3A) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs
index 824dc82..24f8559 100644
--- a/src/f32/coresimd/vec4.rs
+++ b/src/f32/coresimd/vec4.rs
@@ -975,9 +975,9 @@ impl DivAssign<Vec4> for Vec4 {
     }
 }
 
-impl DivAssign<&Self> for Vec4 {
+impl DivAssign<&Vec4> for Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -1099,9 +1099,9 @@ impl MulAssign<Vec4> for Vec4 {
     }
 }
 
-impl MulAssign<&Self> for Vec4 {
+impl MulAssign<&Vec4> for Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1223,9 +1223,9 @@ impl AddAssign<Vec4> for Vec4 {
     }
 }
 
-impl AddAssign<&Self> for Vec4 {
+impl AddAssign<&Vec4> for Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1347,9 +1347,9 @@ impl SubAssign<Vec4> for Vec4 {
     }
 }
 
-impl SubAssign<&Self> for Vec4 {
+impl SubAssign<&Vec4> for Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1471,9 +1471,9 @@ impl RemAssign<Vec4> for Vec4 {
     }
 }
 
-impl RemAssign<&Self> for Vec4 {
+impl RemAssign<&Vec4> for Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/neon/vec3a.rs b/src/f32/neon/vec3a.rs
index fe08d2e..244aaf2 100644
--- a/src/f32/neon/vec3a.rs
+++ b/src/f32/neon/vec3a.rs
@@ -1100,9 +1100,9 @@ impl DivAssign<Vec3A> for Vec3A {
     }
 }
 
-impl DivAssign<&Self> for Vec3A {
+impl DivAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec3A) {
         self.div_assign(*rhs)
     }
 }
@@ -1224,9 +1224,9 @@ impl MulAssign<Vec3A> for Vec3A {
     }
 }
 
-impl MulAssign<&Self> for Vec3A {
+impl MulAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec3A) {
         self.mul_assign(*rhs)
     }
 }
@@ -1348,9 +1348,9 @@ impl AddAssign<Vec3A> for Vec3A {
     }
 }
 
-impl AddAssign<&Self> for Vec3A {
+impl AddAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec3A) {
         self.add_assign(*rhs)
     }
 }
@@ -1472,9 +1472,9 @@ impl SubAssign<Vec3A> for Vec3A {
     }
 }
 
-impl SubAssign<&Self> for Vec3A {
+impl SubAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec3A) {
         self.sub_assign(*rhs)
     }
 }
@@ -1599,9 +1599,9 @@ impl RemAssign<Vec3A> for Vec3A {
     }
 }
 
-impl RemAssign<&Self> for Vec3A {
+impl RemAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec3A) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/neon/vec4.rs b/src/f32/neon/vec4.rs
index c98872e..2a1f093 100644
--- a/src/f32/neon/vec4.rs
+++ b/src/f32/neon/vec4.rs
@@ -1012,9 +1012,9 @@ impl DivAssign<Vec4> for Vec4 {
     }
 }
 
-impl DivAssign<&Self> for Vec4 {
+impl DivAssign<&Vec4> for Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -1136,9 +1136,9 @@ impl MulAssign<Vec4> for Vec4 {
     }
 }
 
-impl MulAssign<&Self> for Vec4 {
+impl MulAssign<&Vec4> for Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1260,9 +1260,9 @@ impl AddAssign<Vec4> for Vec4 {
     }
 }
 
-impl AddAssign<&Self> for Vec4 {
+impl AddAssign<&Vec4> for Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1384,9 +1384,9 @@ impl SubAssign<Vec4> for Vec4 {
     }
 }
 
-impl SubAssign<&Self> for Vec4 {
+impl SubAssign<&Vec4> for Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1511,9 +1511,9 @@ impl RemAssign<Vec4> for Vec4 {
     }
 }
 
-impl RemAssign<&Self> for Vec4 {
+impl RemAssign<&Vec4> for Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/scalar/vec3a.rs b/src/f32/scalar/vec3a.rs
index 4c1c0ce..503568a 100644
--- a/src/f32/scalar/vec3a.rs
+++ b/src/f32/scalar/vec3a.rs
@@ -1102,9 +1102,9 @@ impl DivAssign<Vec3A> for Vec3A {
     }
 }
 
-impl DivAssign<&Self> for Vec3A {
+impl DivAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec3A) {
         self.div_assign(*rhs)
     }
 }
@@ -1242,9 +1242,9 @@ impl MulAssign<Vec3A> for Vec3A {
     }
 }
 
-impl MulAssign<&Self> for Vec3A {
+impl MulAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec3A) {
         self.mul_assign(*rhs)
     }
 }
@@ -1382,9 +1382,9 @@ impl AddAssign<Vec3A> for Vec3A {
     }
 }
 
-impl AddAssign<&Self> for Vec3A {
+impl AddAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec3A) {
         self.add_assign(*rhs)
     }
 }
@@ -1522,9 +1522,9 @@ impl SubAssign<Vec3A> for Vec3A {
     }
 }
 
-impl SubAssign<&Self> for Vec3A {
+impl SubAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec3A) {
         self.sub_assign(*rhs)
     }
 }
@@ -1662,9 +1662,9 @@ impl RemAssign<Vec3A> for Vec3A {
     }
 }
 
-impl RemAssign<&Self> for Vec3A {
+impl RemAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec3A) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/scalar/vec4.rs b/src/f32/scalar/vec4.rs
index bd41448..e5ef427 100644
--- a/src/f32/scalar/vec4.rs
+++ b/src/f32/scalar/vec4.rs
@@ -1095,9 +1095,9 @@ impl DivAssign<Vec4> for Vec4 {
     }
 }
 
-impl DivAssign<&Self> for Vec4 {
+impl DivAssign<&Vec4> for Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -1240,9 +1240,9 @@ impl MulAssign<Vec4> for Vec4 {
     }
 }
 
-impl MulAssign<&Self> for Vec4 {
+impl MulAssign<&Vec4> for Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1385,9 +1385,9 @@ impl AddAssign<Vec4> for Vec4 {
     }
 }
 
-impl AddAssign<&Self> for Vec4 {
+impl AddAssign<&Vec4> for Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1530,9 +1530,9 @@ impl SubAssign<Vec4> for Vec4 {
     }
 }
 
-impl SubAssign<&Self> for Vec4 {
+impl SubAssign<&Vec4> for Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1675,9 +1675,9 @@ impl RemAssign<Vec4> for Vec4 {
     }
 }
 
-impl RemAssign<&Self> for Vec4 {
+impl RemAssign<&Vec4> for Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs
index e9b5e47..d345490 100644
--- a/src/f32/sse2/vec3a.rs
+++ b/src/f32/sse2/vec3a.rs
@@ -1108,9 +1108,9 @@ impl DivAssign<Vec3A> for Vec3A {
     }
 }
 
-impl DivAssign<&Self> for Vec3A {
+impl DivAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec3A) {
         self.div_assign(*rhs)
     }
 }
@@ -1232,9 +1232,9 @@ impl MulAssign<Vec3A> for Vec3A {
     }
 }
 
-impl MulAssign<&Self> for Vec3A {
+impl MulAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec3A) {
         self.mul_assign(*rhs)
     }
 }
@@ -1356,9 +1356,9 @@ impl AddAssign<Vec3A> for Vec3A {
     }
 }
 
-impl AddAssign<&Self> for Vec3A {
+impl AddAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec3A) {
         self.add_assign(*rhs)
     }
 }
@@ -1480,9 +1480,9 @@ impl SubAssign<Vec3A> for Vec3A {
     }
 }
 
-impl SubAssign<&Self> for Vec3A {
+impl SubAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec3A) {
         self.sub_assign(*rhs)
     }
 }
@@ -1607,9 +1607,9 @@ impl RemAssign<Vec3A> for Vec3A {
     }
 }
 
-impl RemAssign<&Self> for Vec3A {
+impl RemAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec3A) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs
index dfab9f2..818566c 100644
--- a/src/f32/sse2/vec4.rs
+++ b/src/f32/sse2/vec4.rs
@@ -1030,9 +1030,9 @@ impl DivAssign<Vec4> for Vec4 {
     }
 }
 
-impl DivAssign<&Self> for Vec4 {
+impl DivAssign<&Vec4> for Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -1154,9 +1154,9 @@ impl MulAssign<Vec4> for Vec4 {
     }
 }
 
-impl MulAssign<&Self> for Vec4 {
+impl MulAssign<&Vec4> for Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1278,9 +1278,9 @@ impl AddAssign<Vec4> for Vec4 {
     }
 }
 
-impl AddAssign<&Self> for Vec4 {
+impl AddAssign<&Vec4> for Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1402,9 +1402,9 @@ impl SubAssign<Vec4> for Vec4 {
     }
 }
 
-impl SubAssign<&Self> for Vec4 {
+impl SubAssign<&Vec4> for Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1529,9 +1529,9 @@ impl RemAssign<Vec4> for Vec4 {
     }
 }
 
-impl RemAssign<&Self> for Vec4 {
+impl RemAssign<&Vec4> for Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/vec2.rs b/src/f32/vec2.rs
index f4b7fdf..79bac00 100644
--- a/src/f32/vec2.rs
+++ b/src/f32/vec2.rs
@@ -1050,9 +1050,9 @@ impl DivAssign<Vec2> for Vec2 {
     }
 }
 
-impl DivAssign<&Self> for Vec2 {
+impl DivAssign<&Vec2> for Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -1185,9 +1185,9 @@ impl MulAssign<Vec2> for Vec2 {
     }
 }
 
-impl MulAssign<&Self> for Vec2 {
+impl MulAssign<&Vec2> for Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -1320,9 +1320,9 @@ impl AddAssign<Vec2> for Vec2 {
     }
 }
 
-impl AddAssign<&Self> for Vec2 {
+impl AddAssign<&Vec2> for Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -1455,9 +1455,9 @@ impl SubAssign<Vec2> for Vec2 {
     }
 }
 
-impl SubAssign<&Self> for Vec2 {
+impl SubAssign<&Vec2> for Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1590,9 +1590,9 @@ impl RemAssign<Vec2> for Vec2 {
     }
 }
 
-impl RemAssign<&Self> for Vec2 {
+impl RemAssign<&Vec2> for Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/vec3.rs b/src/f32/vec3.rs
index f475e1e..b16a291 100644
--- a/src/f32/vec3.rs
+++ b/src/f32/vec3.rs
@@ -1092,9 +1092,9 @@ impl DivAssign<Vec3> for Vec3 {
     }
 }
 
-impl DivAssign<&Self> for Vec3 {
+impl DivAssign<&Vec3> for Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -1232,9 +1232,9 @@ impl MulAssign<Vec3> for Vec3 {
     }
 }
 
-impl MulAssign<&Self> for Vec3 {
+impl MulAssign<&Vec3> for Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -1372,9 +1372,9 @@ impl AddAssign<Vec3> for Vec3 {
     }
 }
 
-impl AddAssign<&Self> for Vec3 {
+impl AddAssign<&Vec3> for Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1512,9 +1512,9 @@ impl SubAssign<Vec3> for Vec3 {
     }
 }
 
-impl SubAssign<&Self> for Vec3 {
+impl SubAssign<&Vec3> for Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1652,9 +1652,9 @@ impl RemAssign<Vec3> for Vec3 {
     }
 }
 
-impl RemAssign<&Self> for Vec3 {
+impl RemAssign<&Vec3> for Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs
index b1d6b90..ea7dee2 100644
--- a/src/f32/wasm32/vec3a.rs
+++ b/src/f32/wasm32/vec3a.rs
@@ -1071,9 +1071,9 @@ impl DivAssign<Vec3A> for Vec3A {
     }
 }
 
-impl DivAssign<&Self> for Vec3A {
+impl DivAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec3A) {
         self.div_assign(*rhs)
     }
 }
@@ -1195,9 +1195,9 @@ impl MulAssign<Vec3A> for Vec3A {
     }
 }
 
-impl MulAssign<&Self> for Vec3A {
+impl MulAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec3A) {
         self.mul_assign(*rhs)
     }
 }
@@ -1319,9 +1319,9 @@ impl AddAssign<Vec3A> for Vec3A {
     }
 }
 
-impl AddAssign<&Self> for Vec3A {
+impl AddAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec3A) {
         self.add_assign(*rhs)
     }
 }
@@ -1443,9 +1443,9 @@ impl SubAssign<Vec3A> for Vec3A {
     }
 }
 
-impl SubAssign<&Self> for Vec3A {
+impl SubAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec3A) {
         self.sub_assign(*rhs)
     }
 }
@@ -1568,9 +1568,9 @@ impl RemAssign<Vec3A> for Vec3A {
     }
 }
 
-impl RemAssign<&Self> for Vec3A {
+impl RemAssign<&Vec3A> for Vec3A {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec3A) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs
index cb1d90b..a7e3290 100644
--- a/src/f32/wasm32/vec4.rs
+++ b/src/f32/wasm32/vec4.rs
@@ -997,9 +997,9 @@ impl DivAssign<Vec4> for Vec4 {
     }
 }
 
-impl DivAssign<&Self> for Vec4 {
+impl DivAssign<&Vec4> for Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -1121,9 +1121,9 @@ impl MulAssign<Vec4> for Vec4 {
     }
 }
 
-impl MulAssign<&Self> for Vec4 {
+impl MulAssign<&Vec4> for Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1245,9 +1245,9 @@ impl AddAssign<Vec4> for Vec4 {
     }
 }
 
-impl AddAssign<&Self> for Vec4 {
+impl AddAssign<&Vec4> for Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1369,9 +1369,9 @@ impl SubAssign<Vec4> for Vec4 {
     }
 }
 
-impl SubAssign<&Self> for Vec4 {
+impl SubAssign<&Vec4> for Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1494,9 +1494,9 @@ impl RemAssign<Vec4> for Vec4 {
     }
 }
 
-impl RemAssign<&Self> for Vec4 {
+impl RemAssign<&Vec4> for Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f64/dvec2.rs b/src/f64/dvec2.rs
index bdd615c..c1edd9c 100644
--- a/src/f64/dvec2.rs
+++ b/src/f64/dvec2.rs
@@ -1050,9 +1050,9 @@ impl DivAssign<DVec2> for DVec2 {
     }
 }
 
-impl DivAssign<&Self> for DVec2 {
+impl DivAssign<&DVec2> for DVec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &DVec2) {
         self.div_assign(*rhs)
     }
 }
@@ -1185,9 +1185,9 @@ impl MulAssign<DVec2> for DVec2 {
     }
 }
 
-impl MulAssign<&Self> for DVec2 {
+impl MulAssign<&DVec2> for DVec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &DVec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -1320,9 +1320,9 @@ impl AddAssign<DVec2> for DVec2 {
     }
 }
 
-impl AddAssign<&Self> for DVec2 {
+impl AddAssign<&DVec2> for DVec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &DVec2) {
         self.add_assign(*rhs)
     }
 }
@@ -1455,9 +1455,9 @@ impl SubAssign<DVec2> for DVec2 {
     }
 }
 
-impl SubAssign<&Self> for DVec2 {
+impl SubAssign<&DVec2> for DVec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &DVec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1590,9 +1590,9 @@ impl RemAssign<DVec2> for DVec2 {
     }
 }
 
-impl RemAssign<&Self> for DVec2 {
+impl RemAssign<&DVec2> for DVec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &DVec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f64/dvec3.rs b/src/f64/dvec3.rs
index 5a67ca0..249bc1d 100644
--- a/src/f64/dvec3.rs
+++ b/src/f64/dvec3.rs
@@ -1099,9 +1099,9 @@ impl DivAssign<DVec3> for DVec3 {
     }
 }
 
-impl DivAssign<&Self> for DVec3 {
+impl DivAssign<&DVec3> for DVec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &DVec3) {
         self.div_assign(*rhs)
     }
 }
@@ -1239,9 +1239,9 @@ impl MulAssign<DVec3> for DVec3 {
     }
 }
 
-impl MulAssign<&Self> for DVec3 {
+impl MulAssign<&DVec3> for DVec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &DVec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -1379,9 +1379,9 @@ impl AddAssign<DVec3> for DVec3 {
     }
 }
 
-impl AddAssign<&Self> for DVec3 {
+impl AddAssign<&DVec3> for DVec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &DVec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1519,9 +1519,9 @@ impl SubAssign<DVec3> for DVec3 {
     }
 }
 
-impl SubAssign<&Self> for DVec3 {
+impl SubAssign<&DVec3> for DVec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &DVec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1659,9 +1659,9 @@ impl RemAssign<DVec3> for DVec3 {
     }
 }
 
-impl RemAssign<&Self> for DVec3 {
+impl RemAssign<&DVec3> for DVec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &DVec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/f64/dvec4.rs b/src/f64/dvec4.rs
index f13647a..b62ced0 100644
--- a/src/f64/dvec4.rs
+++ b/src/f64/dvec4.rs
@@ -1084,9 +1084,9 @@ impl DivAssign<DVec4> for DVec4 {
     }
 }
 
-impl DivAssign<&Self> for DVec4 {
+impl DivAssign<&DVec4> for DVec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &DVec4) {
         self.div_assign(*rhs)
     }
 }
@@ -1229,9 +1229,9 @@ impl MulAssign<DVec4> for DVec4 {
     }
 }
 
-impl MulAssign<&Self> for DVec4 {
+impl MulAssign<&DVec4> for DVec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &DVec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1374,9 +1374,9 @@ impl AddAssign<DVec4> for DVec4 {
     }
 }
 
-impl AddAssign<&Self> for DVec4 {
+impl AddAssign<&DVec4> for DVec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &DVec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1519,9 +1519,9 @@ impl SubAssign<DVec4> for DVec4 {
     }
 }
 
-impl SubAssign<&Self> for DVec4 {
+impl SubAssign<&DVec4> for DVec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &DVec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1664,9 +1664,9 @@ impl RemAssign<DVec4> for DVec4 {
     }
 }
 
-impl RemAssign<&Self> for DVec4 {
+impl RemAssign<&DVec4> for DVec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &DVec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i16/i16vec2.rs b/src/i16/i16vec2.rs
index dc6d6ad..0e58cfe 100644
--- a/src/i16/i16vec2.rs
+++ b/src/i16/i16vec2.rs
@@ -668,9 +668,9 @@ impl DivAssign<I16Vec2> for I16Vec2 {
     }
 }
 
-impl DivAssign<&Self> for I16Vec2 {
+impl DivAssign<&I16Vec2> for I16Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I16Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -803,9 +803,9 @@ impl MulAssign<I16Vec2> for I16Vec2 {
     }
 }
 
-impl MulAssign<&Self> for I16Vec2 {
+impl MulAssign<&I16Vec2> for I16Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I16Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -938,9 +938,9 @@ impl AddAssign<I16Vec2> for I16Vec2 {
     }
 }
 
-impl AddAssign<&Self> for I16Vec2 {
+impl AddAssign<&I16Vec2> for I16Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I16Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -1073,9 +1073,9 @@ impl SubAssign<I16Vec2> for I16Vec2 {
     }
 }
 
-impl SubAssign<&Self> for I16Vec2 {
+impl SubAssign<&I16Vec2> for I16Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I16Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1208,9 +1208,9 @@ impl RemAssign<I16Vec2> for I16Vec2 {
     }
 }
 
-impl RemAssign<&Self> for I16Vec2 {
+impl RemAssign<&I16Vec2> for I16Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I16Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i16/i16vec3.rs b/src/i16/i16vec3.rs
index 0168311..b435754 100644
--- a/src/i16/i16vec3.rs
+++ b/src/i16/i16vec3.rs
@@ -720,9 +720,9 @@ impl DivAssign<I16Vec3> for I16Vec3 {
     }
 }
 
-impl DivAssign<&Self> for I16Vec3 {
+impl DivAssign<&I16Vec3> for I16Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I16Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -860,9 +860,9 @@ impl MulAssign<I16Vec3> for I16Vec3 {
     }
 }
 
-impl MulAssign<&Self> for I16Vec3 {
+impl MulAssign<&I16Vec3> for I16Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I16Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -1000,9 +1000,9 @@ impl AddAssign<I16Vec3> for I16Vec3 {
     }
 }
 
-impl AddAssign<&Self> for I16Vec3 {
+impl AddAssign<&I16Vec3> for I16Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I16Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1140,9 +1140,9 @@ impl SubAssign<I16Vec3> for I16Vec3 {
     }
 }
 
-impl SubAssign<&Self> for I16Vec3 {
+impl SubAssign<&I16Vec3> for I16Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I16Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1280,9 +1280,9 @@ impl RemAssign<I16Vec3> for I16Vec3 {
     }
 }
 
-impl RemAssign<&Self> for I16Vec3 {
+impl RemAssign<&I16Vec3> for I16Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I16Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i16/i16vec4.rs b/src/i16/i16vec4.rs
index b82ef78..7e34644 100644
--- a/src/i16/i16vec4.rs
+++ b/src/i16/i16vec4.rs
@@ -759,9 +759,9 @@ impl DivAssign<I16Vec4> for I16Vec4 {
     }
 }
 
-impl DivAssign<&Self> for I16Vec4 {
+impl DivAssign<&I16Vec4> for I16Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I16Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -904,9 +904,9 @@ impl MulAssign<I16Vec4> for I16Vec4 {
     }
 }
 
-impl MulAssign<&Self> for I16Vec4 {
+impl MulAssign<&I16Vec4> for I16Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I16Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1049,9 +1049,9 @@ impl AddAssign<I16Vec4> for I16Vec4 {
     }
 }
 
-impl AddAssign<&Self> for I16Vec4 {
+impl AddAssign<&I16Vec4> for I16Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I16Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1194,9 +1194,9 @@ impl SubAssign<I16Vec4> for I16Vec4 {
     }
 }
 
-impl SubAssign<&Self> for I16Vec4 {
+impl SubAssign<&I16Vec4> for I16Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I16Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1339,9 +1339,9 @@ impl RemAssign<I16Vec4> for I16Vec4 {
     }
 }
 
-impl RemAssign<&Self> for I16Vec4 {
+impl RemAssign<&I16Vec4> for I16Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I16Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i32/ivec2.rs b/src/i32/ivec2.rs
index f220d1d..90f45cf 100644
--- a/src/i32/ivec2.rs
+++ b/src/i32/ivec2.rs
@@ -668,9 +668,9 @@ impl DivAssign<IVec2> for IVec2 {
     }
 }
 
-impl DivAssign<&Self> for IVec2 {
+impl DivAssign<&IVec2> for IVec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &IVec2) {
         self.div_assign(*rhs)
     }
 }
@@ -803,9 +803,9 @@ impl MulAssign<IVec2> for IVec2 {
     }
 }
 
-impl MulAssign<&Self> for IVec2 {
+impl MulAssign<&IVec2> for IVec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &IVec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -938,9 +938,9 @@ impl AddAssign<IVec2> for IVec2 {
     }
 }
 
-impl AddAssign<&Self> for IVec2 {
+impl AddAssign<&IVec2> for IVec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &IVec2) {
         self.add_assign(*rhs)
     }
 }
@@ -1073,9 +1073,9 @@ impl SubAssign<IVec2> for IVec2 {
     }
 }
 
-impl SubAssign<&Self> for IVec2 {
+impl SubAssign<&IVec2> for IVec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &IVec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1208,9 +1208,9 @@ impl RemAssign<IVec2> for IVec2 {
     }
 }
 
-impl RemAssign<&Self> for IVec2 {
+impl RemAssign<&IVec2> for IVec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &IVec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i32/ivec3.rs b/src/i32/ivec3.rs
index bc15b11..2c17102 100644
--- a/src/i32/ivec3.rs
+++ b/src/i32/ivec3.rs
@@ -720,9 +720,9 @@ impl DivAssign<IVec3> for IVec3 {
     }
 }
 
-impl DivAssign<&Self> for IVec3 {
+impl DivAssign<&IVec3> for IVec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &IVec3) {
         self.div_assign(*rhs)
     }
 }
@@ -860,9 +860,9 @@ impl MulAssign<IVec3> for IVec3 {
     }
 }
 
-impl MulAssign<&Self> for IVec3 {
+impl MulAssign<&IVec3> for IVec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &IVec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -1000,9 +1000,9 @@ impl AddAssign<IVec3> for IVec3 {
     }
 }
 
-impl AddAssign<&Self> for IVec3 {
+impl AddAssign<&IVec3> for IVec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &IVec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1140,9 +1140,9 @@ impl SubAssign<IVec3> for IVec3 {
     }
 }
 
-impl SubAssign<&Self> for IVec3 {
+impl SubAssign<&IVec3> for IVec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &IVec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1280,9 +1280,9 @@ impl RemAssign<IVec3> for IVec3 {
     }
 }
 
-impl RemAssign<&Self> for IVec3 {
+impl RemAssign<&IVec3> for IVec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &IVec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i32/ivec4.rs b/src/i32/ivec4.rs
index eef4c8d..ede2e6c 100644
--- a/src/i32/ivec4.rs
+++ b/src/i32/ivec4.rs
@@ -759,9 +759,9 @@ impl DivAssign<IVec4> for IVec4 {
     }
 }
 
-impl DivAssign<&Self> for IVec4 {
+impl DivAssign<&IVec4> for IVec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &IVec4) {
         self.div_assign(*rhs)
     }
 }
@@ -904,9 +904,9 @@ impl MulAssign<IVec4> for IVec4 {
     }
 }
 
-impl MulAssign<&Self> for IVec4 {
+impl MulAssign<&IVec4> for IVec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &IVec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1049,9 +1049,9 @@ impl AddAssign<IVec4> for IVec4 {
     }
 }
 
-impl AddAssign<&Self> for IVec4 {
+impl AddAssign<&IVec4> for IVec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &IVec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1194,9 +1194,9 @@ impl SubAssign<IVec4> for IVec4 {
     }
 }
 
-impl SubAssign<&Self> for IVec4 {
+impl SubAssign<&IVec4> for IVec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &IVec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1339,9 +1339,9 @@ impl RemAssign<IVec4> for IVec4 {
     }
 }
 
-impl RemAssign<&Self> for IVec4 {
+impl RemAssign<&IVec4> for IVec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &IVec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i64/i64vec2.rs b/src/i64/i64vec2.rs
index 0873aa3..9a4c554 100644
--- a/src/i64/i64vec2.rs
+++ b/src/i64/i64vec2.rs
@@ -668,9 +668,9 @@ impl DivAssign<I64Vec2> for I64Vec2 {
     }
 }
 
-impl DivAssign<&Self> for I64Vec2 {
+impl DivAssign<&I64Vec2> for I64Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I64Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -803,9 +803,9 @@ impl MulAssign<I64Vec2> for I64Vec2 {
     }
 }
 
-impl MulAssign<&Self> for I64Vec2 {
+impl MulAssign<&I64Vec2> for I64Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I64Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -938,9 +938,9 @@ impl AddAssign<I64Vec2> for I64Vec2 {
     }
 }
 
-impl AddAssign<&Self> for I64Vec2 {
+impl AddAssign<&I64Vec2> for I64Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I64Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -1073,9 +1073,9 @@ impl SubAssign<I64Vec2> for I64Vec2 {
     }
 }
 
-impl SubAssign<&Self> for I64Vec2 {
+impl SubAssign<&I64Vec2> for I64Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I64Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1208,9 +1208,9 @@ impl RemAssign<I64Vec2> for I64Vec2 {
     }
 }
 
-impl RemAssign<&Self> for I64Vec2 {
+impl RemAssign<&I64Vec2> for I64Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I64Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i64/i64vec3.rs b/src/i64/i64vec3.rs
index 5f42aee..dc46af0 100644
--- a/src/i64/i64vec3.rs
+++ b/src/i64/i64vec3.rs
@@ -720,9 +720,9 @@ impl DivAssign<I64Vec3> for I64Vec3 {
     }
 }
 
-impl DivAssign<&Self> for I64Vec3 {
+impl DivAssign<&I64Vec3> for I64Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I64Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -860,9 +860,9 @@ impl MulAssign<I64Vec3> for I64Vec3 {
     }
 }
 
-impl MulAssign<&Self> for I64Vec3 {
+impl MulAssign<&I64Vec3> for I64Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I64Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -1000,9 +1000,9 @@ impl AddAssign<I64Vec3> for I64Vec3 {
     }
 }
 
-impl AddAssign<&Self> for I64Vec3 {
+impl AddAssign<&I64Vec3> for I64Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I64Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1140,9 +1140,9 @@ impl SubAssign<I64Vec3> for I64Vec3 {
     }
 }
 
-impl SubAssign<&Self> for I64Vec3 {
+impl SubAssign<&I64Vec3> for I64Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I64Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1280,9 +1280,9 @@ impl RemAssign<I64Vec3> for I64Vec3 {
     }
 }
 
-impl RemAssign<&Self> for I64Vec3 {
+impl RemAssign<&I64Vec3> for I64Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I64Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i64/i64vec4.rs b/src/i64/i64vec4.rs
index 667756a..0b3d3bb 100644
--- a/src/i64/i64vec4.rs
+++ b/src/i64/i64vec4.rs
@@ -759,9 +759,9 @@ impl DivAssign<I64Vec4> for I64Vec4 {
     }
 }
 
-impl DivAssign<&Self> for I64Vec4 {
+impl DivAssign<&I64Vec4> for I64Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I64Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -904,9 +904,9 @@ impl MulAssign<I64Vec4> for I64Vec4 {
     }
 }
 
-impl MulAssign<&Self> for I64Vec4 {
+impl MulAssign<&I64Vec4> for I64Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I64Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1049,9 +1049,9 @@ impl AddAssign<I64Vec4> for I64Vec4 {
     }
 }
 
-impl AddAssign<&Self> for I64Vec4 {
+impl AddAssign<&I64Vec4> for I64Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I64Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1194,9 +1194,9 @@ impl SubAssign<I64Vec4> for I64Vec4 {
     }
 }
 
-impl SubAssign<&Self> for I64Vec4 {
+impl SubAssign<&I64Vec4> for I64Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I64Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1339,9 +1339,9 @@ impl RemAssign<I64Vec4> for I64Vec4 {
     }
 }
 
-impl RemAssign<&Self> for I64Vec4 {
+impl RemAssign<&I64Vec4> for I64Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I64Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i8/i8vec2.rs b/src/i8/i8vec2.rs
index ee75627..398760c 100644
--- a/src/i8/i8vec2.rs
+++ b/src/i8/i8vec2.rs
@@ -668,9 +668,9 @@ impl DivAssign<I8Vec2> for I8Vec2 {
     }
 }
 
-impl DivAssign<&Self> for I8Vec2 {
+impl DivAssign<&I8Vec2> for I8Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I8Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -803,9 +803,9 @@ impl MulAssign<I8Vec2> for I8Vec2 {
     }
 }
 
-impl MulAssign<&Self> for I8Vec2 {
+impl MulAssign<&I8Vec2> for I8Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I8Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -938,9 +938,9 @@ impl AddAssign<I8Vec2> for I8Vec2 {
     }
 }
 
-impl AddAssign<&Self> for I8Vec2 {
+impl AddAssign<&I8Vec2> for I8Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I8Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -1073,9 +1073,9 @@ impl SubAssign<I8Vec2> for I8Vec2 {
     }
 }
 
-impl SubAssign<&Self> for I8Vec2 {
+impl SubAssign<&I8Vec2> for I8Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I8Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1208,9 +1208,9 @@ impl RemAssign<I8Vec2> for I8Vec2 {
     }
 }
 
-impl RemAssign<&Self> for I8Vec2 {
+impl RemAssign<&I8Vec2> for I8Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I8Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i8/i8vec3.rs b/src/i8/i8vec3.rs
index 6609475..382b9a8 100644
--- a/src/i8/i8vec3.rs
+++ b/src/i8/i8vec3.rs
@@ -720,9 +720,9 @@ impl DivAssign<I8Vec3> for I8Vec3 {
     }
 }
 
-impl DivAssign<&Self> for I8Vec3 {
+impl DivAssign<&I8Vec3> for I8Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I8Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -860,9 +860,9 @@ impl MulAssign<I8Vec3> for I8Vec3 {
     }
 }
 
-impl MulAssign<&Self> for I8Vec3 {
+impl MulAssign<&I8Vec3> for I8Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I8Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -1000,9 +1000,9 @@ impl AddAssign<I8Vec3> for I8Vec3 {
     }
 }
 
-impl AddAssign<&Self> for I8Vec3 {
+impl AddAssign<&I8Vec3> for I8Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I8Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1140,9 +1140,9 @@ impl SubAssign<I8Vec3> for I8Vec3 {
     }
 }
 
-impl SubAssign<&Self> for I8Vec3 {
+impl SubAssign<&I8Vec3> for I8Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I8Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1280,9 +1280,9 @@ impl RemAssign<I8Vec3> for I8Vec3 {
     }
 }
 
-impl RemAssign<&Self> for I8Vec3 {
+impl RemAssign<&I8Vec3> for I8Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I8Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/i8/i8vec4.rs b/src/i8/i8vec4.rs
index e1e797d..2445a84 100644
--- a/src/i8/i8vec4.rs
+++ b/src/i8/i8vec4.rs
@@ -759,9 +759,9 @@ impl DivAssign<I8Vec4> for I8Vec4 {
     }
 }
 
-impl DivAssign<&Self> for I8Vec4 {
+impl DivAssign<&I8Vec4> for I8Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &I8Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -904,9 +904,9 @@ impl MulAssign<I8Vec4> for I8Vec4 {
     }
 }
 
-impl MulAssign<&Self> for I8Vec4 {
+impl MulAssign<&I8Vec4> for I8Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &I8Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -1049,9 +1049,9 @@ impl AddAssign<I8Vec4> for I8Vec4 {
     }
 }
 
-impl AddAssign<&Self> for I8Vec4 {
+impl AddAssign<&I8Vec4> for I8Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &I8Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1194,9 +1194,9 @@ impl SubAssign<I8Vec4> for I8Vec4 {
     }
 }
 
-impl SubAssign<&Self> for I8Vec4 {
+impl SubAssign<&I8Vec4> for I8Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &I8Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1339,9 +1339,9 @@ impl RemAssign<I8Vec4> for I8Vec4 {
     }
 }
 
-impl RemAssign<&Self> for I8Vec4 {
+impl RemAssign<&I8Vec4> for I8Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &I8Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u16/u16vec2.rs b/src/u16/u16vec2.rs
index 907f8a8..67d74be 100644
--- a/src/u16/u16vec2.rs
+++ b/src/u16/u16vec2.rs
@@ -539,9 +539,9 @@ impl DivAssign<U16Vec2> for U16Vec2 {
     }
 }
 
-impl DivAssign<&Self> for U16Vec2 {
+impl DivAssign<&U16Vec2> for U16Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U16Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -674,9 +674,9 @@ impl MulAssign<U16Vec2> for U16Vec2 {
     }
 }
 
-impl MulAssign<&Self> for U16Vec2 {
+impl MulAssign<&U16Vec2> for U16Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U16Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -809,9 +809,9 @@ impl AddAssign<U16Vec2> for U16Vec2 {
     }
 }
 
-impl AddAssign<&Self> for U16Vec2 {
+impl AddAssign<&U16Vec2> for U16Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U16Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -944,9 +944,9 @@ impl SubAssign<U16Vec2> for U16Vec2 {
     }
 }
 
-impl SubAssign<&Self> for U16Vec2 {
+impl SubAssign<&U16Vec2> for U16Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U16Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1079,9 +1079,9 @@ impl RemAssign<U16Vec2> for U16Vec2 {
     }
 }
 
-impl RemAssign<&Self> for U16Vec2 {
+impl RemAssign<&U16Vec2> for U16Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U16Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u16/u16vec3.rs b/src/u16/u16vec3.rs
index 14bb406..43e0023 100644
--- a/src/u16/u16vec3.rs
+++ b/src/u16/u16vec3.rs
@@ -607,9 +607,9 @@ impl DivAssign<U16Vec3> for U16Vec3 {
     }
 }
 
-impl DivAssign<&Self> for U16Vec3 {
+impl DivAssign<&U16Vec3> for U16Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U16Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -747,9 +747,9 @@ impl MulAssign<U16Vec3> for U16Vec3 {
     }
 }
 
-impl MulAssign<&Self> for U16Vec3 {
+impl MulAssign<&U16Vec3> for U16Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U16Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -887,9 +887,9 @@ impl AddAssign<U16Vec3> for U16Vec3 {
     }
 }
 
-impl AddAssign<&Self> for U16Vec3 {
+impl AddAssign<&U16Vec3> for U16Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U16Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1027,9 +1027,9 @@ impl SubAssign<U16Vec3> for U16Vec3 {
     }
 }
 
-impl SubAssign<&Self> for U16Vec3 {
+impl SubAssign<&U16Vec3> for U16Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U16Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1167,9 +1167,9 @@ impl RemAssign<U16Vec3> for U16Vec3 {
     }
 }
 
-impl RemAssign<&Self> for U16Vec3 {
+impl RemAssign<&U16Vec3> for U16Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U16Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u16/u16vec4.rs b/src/u16/u16vec4.rs
index 0ff3b72..05b6632 100644
--- a/src/u16/u16vec4.rs
+++ b/src/u16/u16vec4.rs
@@ -636,9 +636,9 @@ impl DivAssign<U16Vec4> for U16Vec4 {
     }
 }
 
-impl DivAssign<&Self> for U16Vec4 {
+impl DivAssign<&U16Vec4> for U16Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U16Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -781,9 +781,9 @@ impl MulAssign<U16Vec4> for U16Vec4 {
     }
 }
 
-impl MulAssign<&Self> for U16Vec4 {
+impl MulAssign<&U16Vec4> for U16Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U16Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -926,9 +926,9 @@ impl AddAssign<U16Vec4> for U16Vec4 {
     }
 }
 
-impl AddAssign<&Self> for U16Vec4 {
+impl AddAssign<&U16Vec4> for U16Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U16Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1071,9 +1071,9 @@ impl SubAssign<U16Vec4> for U16Vec4 {
     }
 }
 
-impl SubAssign<&Self> for U16Vec4 {
+impl SubAssign<&U16Vec4> for U16Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U16Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1216,9 +1216,9 @@ impl RemAssign<U16Vec4> for U16Vec4 {
     }
 }
 
-impl RemAssign<&Self> for U16Vec4 {
+impl RemAssign<&U16Vec4> for U16Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U16Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u32/uvec2.rs b/src/u32/uvec2.rs
index e81e003..ca91ef0 100644
--- a/src/u32/uvec2.rs
+++ b/src/u32/uvec2.rs
@@ -539,9 +539,9 @@ impl DivAssign<UVec2> for UVec2 {
     }
 }
 
-impl DivAssign<&Self> for UVec2 {
+impl DivAssign<&UVec2> for UVec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &UVec2) {
         self.div_assign(*rhs)
     }
 }
@@ -674,9 +674,9 @@ impl MulAssign<UVec2> for UVec2 {
     }
 }
 
-impl MulAssign<&Self> for UVec2 {
+impl MulAssign<&UVec2> for UVec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &UVec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -809,9 +809,9 @@ impl AddAssign<UVec2> for UVec2 {
     }
 }
 
-impl AddAssign<&Self> for UVec2 {
+impl AddAssign<&UVec2> for UVec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &UVec2) {
         self.add_assign(*rhs)
     }
 }
@@ -944,9 +944,9 @@ impl SubAssign<UVec2> for UVec2 {
     }
 }
 
-impl SubAssign<&Self> for UVec2 {
+impl SubAssign<&UVec2> for UVec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &UVec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1079,9 +1079,9 @@ impl RemAssign<UVec2> for UVec2 {
     }
 }
 
-impl RemAssign<&Self> for UVec2 {
+impl RemAssign<&UVec2> for UVec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &UVec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u32/uvec3.rs b/src/u32/uvec3.rs
index 5ac4d49..28fe407 100644
--- a/src/u32/uvec3.rs
+++ b/src/u32/uvec3.rs
@@ -607,9 +607,9 @@ impl DivAssign<UVec3> for UVec3 {
     }
 }
 
-impl DivAssign<&Self> for UVec3 {
+impl DivAssign<&UVec3> for UVec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &UVec3) {
         self.div_assign(*rhs)
     }
 }
@@ -747,9 +747,9 @@ impl MulAssign<UVec3> for UVec3 {
     }
 }
 
-impl MulAssign<&Self> for UVec3 {
+impl MulAssign<&UVec3> for UVec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &UVec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -887,9 +887,9 @@ impl AddAssign<UVec3> for UVec3 {
     }
 }
 
-impl AddAssign<&Self> for UVec3 {
+impl AddAssign<&UVec3> for UVec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &UVec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1027,9 +1027,9 @@ impl SubAssign<UVec3> for UVec3 {
     }
 }
 
-impl SubAssign<&Self> for UVec3 {
+impl SubAssign<&UVec3> for UVec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &UVec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1167,9 +1167,9 @@ impl RemAssign<UVec3> for UVec3 {
     }
 }
 
-impl RemAssign<&Self> for UVec3 {
+impl RemAssign<&UVec3> for UVec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &UVec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u32/uvec4.rs b/src/u32/uvec4.rs
index f02182f..08795b1 100644
--- a/src/u32/uvec4.rs
+++ b/src/u32/uvec4.rs
@@ -636,9 +636,9 @@ impl DivAssign<UVec4> for UVec4 {
     }
 }
 
-impl DivAssign<&Self> for UVec4 {
+impl DivAssign<&UVec4> for UVec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &UVec4) {
         self.div_assign(*rhs)
     }
 }
@@ -781,9 +781,9 @@ impl MulAssign<UVec4> for UVec4 {
     }
 }
 
-impl MulAssign<&Self> for UVec4 {
+impl MulAssign<&UVec4> for UVec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &UVec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -926,9 +926,9 @@ impl AddAssign<UVec4> for UVec4 {
     }
 }
 
-impl AddAssign<&Self> for UVec4 {
+impl AddAssign<&UVec4> for UVec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &UVec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1071,9 +1071,9 @@ impl SubAssign<UVec4> for UVec4 {
     }
 }
 
-impl SubAssign<&Self> for UVec4 {
+impl SubAssign<&UVec4> for UVec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &UVec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1216,9 +1216,9 @@ impl RemAssign<UVec4> for UVec4 {
     }
 }
 
-impl RemAssign<&Self> for UVec4 {
+impl RemAssign<&UVec4> for UVec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &UVec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u64/u64vec2.rs b/src/u64/u64vec2.rs
index 83f333b..fba69e0 100644
--- a/src/u64/u64vec2.rs
+++ b/src/u64/u64vec2.rs
@@ -539,9 +539,9 @@ impl DivAssign<U64Vec2> for U64Vec2 {
     }
 }
 
-impl DivAssign<&Self> for U64Vec2 {
+impl DivAssign<&U64Vec2> for U64Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U64Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -674,9 +674,9 @@ impl MulAssign<U64Vec2> for U64Vec2 {
     }
 }
 
-impl MulAssign<&Self> for U64Vec2 {
+impl MulAssign<&U64Vec2> for U64Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U64Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -809,9 +809,9 @@ impl AddAssign<U64Vec2> for U64Vec2 {
     }
 }
 
-impl AddAssign<&Self> for U64Vec2 {
+impl AddAssign<&U64Vec2> for U64Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U64Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -944,9 +944,9 @@ impl SubAssign<U64Vec2> for U64Vec2 {
     }
 }
 
-impl SubAssign<&Self> for U64Vec2 {
+impl SubAssign<&U64Vec2> for U64Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U64Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1079,9 +1079,9 @@ impl RemAssign<U64Vec2> for U64Vec2 {
     }
 }
 
-impl RemAssign<&Self> for U64Vec2 {
+impl RemAssign<&U64Vec2> for U64Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U64Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u64/u64vec3.rs b/src/u64/u64vec3.rs
index 585fbb5..3607882 100644
--- a/src/u64/u64vec3.rs
+++ b/src/u64/u64vec3.rs
@@ -607,9 +607,9 @@ impl DivAssign<U64Vec3> for U64Vec3 {
     }
 }
 
-impl DivAssign<&Self> for U64Vec3 {
+impl DivAssign<&U64Vec3> for U64Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U64Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -747,9 +747,9 @@ impl MulAssign<U64Vec3> for U64Vec3 {
     }
 }
 
-impl MulAssign<&Self> for U64Vec3 {
+impl MulAssign<&U64Vec3> for U64Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U64Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -887,9 +887,9 @@ impl AddAssign<U64Vec3> for U64Vec3 {
     }
 }
 
-impl AddAssign<&Self> for U64Vec3 {
+impl AddAssign<&U64Vec3> for U64Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U64Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1027,9 +1027,9 @@ impl SubAssign<U64Vec3> for U64Vec3 {
     }
 }
 
-impl SubAssign<&Self> for U64Vec3 {
+impl SubAssign<&U64Vec3> for U64Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U64Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1167,9 +1167,9 @@ impl RemAssign<U64Vec3> for U64Vec3 {
     }
 }
 
-impl RemAssign<&Self> for U64Vec3 {
+impl RemAssign<&U64Vec3> for U64Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U64Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u64/u64vec4.rs b/src/u64/u64vec4.rs
index 07ce227..24c997b 100644
--- a/src/u64/u64vec4.rs
+++ b/src/u64/u64vec4.rs
@@ -636,9 +636,9 @@ impl DivAssign<U64Vec4> for U64Vec4 {
     }
 }
 
-impl DivAssign<&Self> for U64Vec4 {
+impl DivAssign<&U64Vec4> for U64Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U64Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -781,9 +781,9 @@ impl MulAssign<U64Vec4> for U64Vec4 {
     }
 }
 
-impl MulAssign<&Self> for U64Vec4 {
+impl MulAssign<&U64Vec4> for U64Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U64Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -926,9 +926,9 @@ impl AddAssign<U64Vec4> for U64Vec4 {
     }
 }
 
-impl AddAssign<&Self> for U64Vec4 {
+impl AddAssign<&U64Vec4> for U64Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U64Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1071,9 +1071,9 @@ impl SubAssign<U64Vec4> for U64Vec4 {
     }
 }
 
-impl SubAssign<&Self> for U64Vec4 {
+impl SubAssign<&U64Vec4> for U64Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U64Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1216,9 +1216,9 @@ impl RemAssign<U64Vec4> for U64Vec4 {
     }
 }
 
-impl RemAssign<&Self> for U64Vec4 {
+impl RemAssign<&U64Vec4> for U64Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U64Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u8/u8vec2.rs b/src/u8/u8vec2.rs
index cf2c1bb..cc6decf 100644
--- a/src/u8/u8vec2.rs
+++ b/src/u8/u8vec2.rs
@@ -539,9 +539,9 @@ impl DivAssign<U8Vec2> for U8Vec2 {
     }
 }
 
-impl DivAssign<&Self> for U8Vec2 {
+impl DivAssign<&U8Vec2> for U8Vec2 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U8Vec2) {
         self.div_assign(*rhs)
     }
 }
@@ -674,9 +674,9 @@ impl MulAssign<U8Vec2> for U8Vec2 {
     }
 }
 
-impl MulAssign<&Self> for U8Vec2 {
+impl MulAssign<&U8Vec2> for U8Vec2 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U8Vec2) {
         self.mul_assign(*rhs)
     }
 }
@@ -809,9 +809,9 @@ impl AddAssign<U8Vec2> for U8Vec2 {
     }
 }
 
-impl AddAssign<&Self> for U8Vec2 {
+impl AddAssign<&U8Vec2> for U8Vec2 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U8Vec2) {
         self.add_assign(*rhs)
     }
 }
@@ -944,9 +944,9 @@ impl SubAssign<U8Vec2> for U8Vec2 {
     }
 }
 
-impl SubAssign<&Self> for U8Vec2 {
+impl SubAssign<&U8Vec2> for U8Vec2 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U8Vec2) {
         self.sub_assign(*rhs)
     }
 }
@@ -1079,9 +1079,9 @@ impl RemAssign<U8Vec2> for U8Vec2 {
     }
 }
 
-impl RemAssign<&Self> for U8Vec2 {
+impl RemAssign<&U8Vec2> for U8Vec2 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U8Vec2) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u8/u8vec3.rs b/src/u8/u8vec3.rs
index 09ba3f4..752c12f 100644
--- a/src/u8/u8vec3.rs
+++ b/src/u8/u8vec3.rs
@@ -607,9 +607,9 @@ impl DivAssign<U8Vec3> for U8Vec3 {
     }
 }
 
-impl DivAssign<&Self> for U8Vec3 {
+impl DivAssign<&U8Vec3> for U8Vec3 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U8Vec3) {
         self.div_assign(*rhs)
     }
 }
@@ -747,9 +747,9 @@ impl MulAssign<U8Vec3> for U8Vec3 {
     }
 }
 
-impl MulAssign<&Self> for U8Vec3 {
+impl MulAssign<&U8Vec3> for U8Vec3 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U8Vec3) {
         self.mul_assign(*rhs)
     }
 }
@@ -887,9 +887,9 @@ impl AddAssign<U8Vec3> for U8Vec3 {
     }
 }
 
-impl AddAssign<&Self> for U8Vec3 {
+impl AddAssign<&U8Vec3> for U8Vec3 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U8Vec3) {
         self.add_assign(*rhs)
     }
 }
@@ -1027,9 +1027,9 @@ impl SubAssign<U8Vec3> for U8Vec3 {
     }
 }
 
-impl SubAssign<&Self> for U8Vec3 {
+impl SubAssign<&U8Vec3> for U8Vec3 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U8Vec3) {
         self.sub_assign(*rhs)
     }
 }
@@ -1167,9 +1167,9 @@ impl RemAssign<U8Vec3> for U8Vec3 {
     }
 }
 
-impl RemAssign<&Self> for U8Vec3 {
+impl RemAssign<&U8Vec3> for U8Vec3 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U8Vec3) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/src/u8/u8vec4.rs b/src/u8/u8vec4.rs
index 1b64aa8..29c0676 100644
--- a/src/u8/u8vec4.rs
+++ b/src/u8/u8vec4.rs
@@ -636,9 +636,9 @@ impl DivAssign<U8Vec4> for U8Vec4 {
     }
 }
 
-impl DivAssign<&Self> for U8Vec4 {
+impl DivAssign<&U8Vec4> for U8Vec4 {
     #[inline]
-    fn div_assign(&mut self, rhs: &Self) {
+    fn div_assign(&mut self, rhs: &U8Vec4) {
         self.div_assign(*rhs)
     }
 }
@@ -781,9 +781,9 @@ impl MulAssign<U8Vec4> for U8Vec4 {
     }
 }
 
-impl MulAssign<&Self> for U8Vec4 {
+impl MulAssign<&U8Vec4> for U8Vec4 {
     #[inline]
-    fn mul_assign(&mut self, rhs: &Self) {
+    fn mul_assign(&mut self, rhs: &U8Vec4) {
         self.mul_assign(*rhs)
     }
 }
@@ -926,9 +926,9 @@ impl AddAssign<U8Vec4> for U8Vec4 {
     }
 }
 
-impl AddAssign<&Self> for U8Vec4 {
+impl AddAssign<&U8Vec4> for U8Vec4 {
     #[inline]
-    fn add_assign(&mut self, rhs: &Self) {
+    fn add_assign(&mut self, rhs: &U8Vec4) {
         self.add_assign(*rhs)
     }
 }
@@ -1071,9 +1071,9 @@ impl SubAssign<U8Vec4> for U8Vec4 {
     }
 }
 
-impl SubAssign<&Self> for U8Vec4 {
+impl SubAssign<&U8Vec4> for U8Vec4 {
     #[inline]
-    fn sub_assign(&mut self, rhs: &Self) {
+    fn sub_assign(&mut self, rhs: &U8Vec4) {
         self.sub_assign(*rhs)
     }
 }
@@ -1216,9 +1216,9 @@ impl RemAssign<U8Vec4> for U8Vec4 {
     }
 }
 
-impl RemAssign<&Self> for U8Vec4 {
+impl RemAssign<&U8Vec4> for U8Vec4 {
     #[inline]
-    fn rem_assign(&mut self, rhs: &Self) {
+    fn rem_assign(&mut self, rhs: &U8Vec4) {
         self.rem_assign(*rhs)
     }
 }
diff --git a/swizzlegen/Cargo.toml b/swizzlegen/Cargo.toml
new file mode 100644
index 0000000..7cd8d6d
--- /dev/null
+++ b/swizzlegen/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "swizzlegen"
+version = "0.1.0"
+authors = ["Cameron Hart <cameron.hart@gmail.com>"]
+edition = "2021"
+
+[dependencies]
diff --git a/swizzlegen/src/main.rs b/swizzlegen/src/main.rs
new file mode 100644
index 0000000..e5968d9
--- /dev/null
+++ b/swizzlegen/src/main.rs
@@ -0,0 +1,228 @@
+use std::fs::File;
+use std::io::{Result, Write};
+
+const E: [char; 4] = ['x', 'y', 'z', 'w']; // element name
+const V: [&str; 4] = ["1", "2", "3", "4"]; // element value
+
+fn write_swizzle_head(out: &mut impl Write) -> Result<()> {
+    writeln!(out, "// Generated by swizzlegen. Do not edit.")?;
+    Ok(())
+}
+
+fn write_loops_vec4<W, F4>(out: &mut W, size: usize, vec4fn: F4) -> Result<()>
+where
+    W: Write,
+    F4: Fn(&mut W, usize, usize, usize, usize) -> Result<()>,
+{
+    for e0 in 0..size {
+        for e1 in 0..size {
+            for e2 in 0..size {
+                for e3 in 0..size {
+                    if size == 4 && e0 == 0 && e1 == 1 && e2 == 2 && e3 == 3 {
+                        continue;
+                    }
+                    vec4fn(out, e0, e1, e2, e3)?;
+                }
+            }
+        }
+    }
+    Ok(())
+}
+
+fn write_loops_vec3<W, F3>(out: &mut W, size: usize, vec3fn: F3) -> Result<()>
+where
+    W: Write,
+    F3: Fn(&mut W, usize, usize, usize) -> Result<()>,
+{
+    for e0 in 0..size {
+        for e1 in 0..size {
+            for e2 in 0..size {
+                if size == 3 && e0 == 0 && e1 == 1 && e2 == 2 {
+                    continue;
+                }
+                vec3fn(out, e0, e1, e2)?;
+            }
+        }
+    }
+    Ok(())
+}
+
+fn write_loops_vec2<W, F2>(out: &mut W, size: usize, vec2fn: F2) -> Result<()>
+where
+    W: Write,
+    F2: Fn(&mut W, usize, usize) -> Result<()>,
+{
+    for e0 in 0..size {
+        for e1 in 0..size {
+            if size == 2 && e0 == 0 && e1 == 1 {
+                continue;
+            }
+            vec2fn(out, e0, e1)?;
+        }
+    }
+    Ok(())
+}
+
+fn write_test_vec4(
+    out: &mut impl Write,
+    t: &str,
+    vec4t: &str,
+    vec3t: &str,
+    vec2t: &str,
+) -> Result<()> {
+    const SIZE: usize = 4;
+
+    write!(
+        out,
+        r#"
+glam_test!(test_{}_swizzles, {{
+    let v = {}(1_{}, 2_{}, 3_{}, 4_{});
+"#,
+        vec4t, vec4t, t, t, t, t,
+    )?;
+
+    writeln!(out, "    assert_eq!(v, v.xyzw());")?;
+
+    write_test_loops(out, SIZE, t, vec4t, vec3t, vec2t)?;
+
+    writeln!(out, "}});")?;
+
+    Ok(())
+}
+
+fn write_test_vec3(
+    out: &mut impl Write,
+    t: &str,
+    vec4t: &str,
+    vec3t: &str,
+    vec2t: &str,
+) -> Result<()> {
+    const SIZE: usize = 3;
+
+    write!(
+        out,
+        r#"
+glam_test!(test_{}_swizzles, {{
+    let v = {}(1_{}, 2_{}, 3_{});
+"#,
+        vec3t, vec3t, t, t, t,
+    )?;
+
+    writeln!(out, "    assert_eq!(v, v.xyz());")?;
+
+    write_test_loops(out, SIZE, t, vec4t, vec3t, vec2t)?;
+
+    writeln!(out, "}});")?;
+
+    Ok(())
+}
+
+fn write_test_vec2(
+    out: &mut impl Write,
+    t: &str,
+    vec4t: &str,
+    vec3t: &str,
+    vec2t: &str,
+) -> Result<()> {
+    const SIZE: usize = 2;
+
+    write!(
+        out,
+        r#"
+glam_test!(test_{}_swizzles, {{
+    let v = {}(1_{}, 2_{});
+"#,
+        vec2t, vec2t, t, t,
+    )?;
+
+    writeln!(out, "    assert_eq!(v, v.xy());")?;
+
+    write_test_loops(out, SIZE, t, vec4t, vec3t, vec2t)?;
+
+    writeln!(out, "}});")?;
+
+    Ok(())
+}
+
+fn write_test_loops(
+    out: &mut impl Write,
+    size: usize,
+    t: &str,
+    vec4t: &str,
+    vec3t: &str,
+    vec2t: &str,
+) -> Result<()> {
+    write_loops_vec4(out, size, |out, e0, e1, e2, e3| {
+        writeln!(
+            out,
+            "    assert_eq!(v.{}{}{}{}(), {}({}_{}, {}_{}, {}_{}, {}_{}));",
+            E[e0], E[e1], E[e2], E[e3], vec4t, V[e0], t, V[e1], t, V[e2], t, V[e3], t
+        )
+    })?;
+    write_loops_vec3(out, size, |out, e0, e1, e2| {
+        writeln!(
+            out,
+            "    assert_eq!(v.{}{}{}(), {}({}_{}, {}_{}, {}_{}));",
+            E[e0], E[e1], E[e2], vec3t, V[e0], t, V[e1], t, V[e2], t,
+        )
+    })?;
+    write_loops_vec2(out, size, |out, e0, e1| {
+        writeln!(
+            out,
+            "    assert_eq!(v.{}{}(), {}({}_{}, {}_{}));",
+            E[e0], E[e1], vec2t, V[e0], t, V[e1], t,
+        )
+    })?;
+    Ok(())
+}
+
+fn write_swizzle_tests_preamble(filename: &str) -> Result<impl Write> {
+    let mut out = File::create(filename)?;
+    write_swizzle_head(&mut out)?;
+    writeln!(
+        &mut out,
+        r#"#[macro_use]
+mod support;
+use glam::*;"#
+    )?;
+    Ok(out)
+}
+
+fn write_swizzle_tests_scalar(scalar_t: &str, prefix: &str) -> Result<()> {
+    let vec4_t = format!("{prefix}vec4");
+    let vec3_t = format!("{prefix}vec3");
+    let vec2_t = format!("{prefix}vec2");
+    let mut out = write_swizzle_tests_preamble(&format!("../tests/swizzles_{scalar_t}.rs"))?;
+    write_test_vec4(&mut out, scalar_t, &vec4_t, &vec3_t, &vec2_t)?;
+    if scalar_t == "f32" {
+        write_test_vec3(&mut out, "f32", "vec4", "vec3a", "vec2")?;
+    }
+    write_test_vec3(&mut out, scalar_t, &vec4_t, &vec3_t, &vec2_t)?;
+    write_test_vec2(&mut out, scalar_t, &vec4_t, &vec3_t, &vec2_t)?;
+    Ok(())
+}
+
+fn write_swizzle_tests() -> Result<()> {
+    write_swizzle_tests_scalar("f32", "")?;
+    write_swizzle_tests_scalar("f64", "d")?;
+
+    write_swizzle_tests_scalar("i64", "i64")?;
+    write_swizzle_tests_scalar("i32", "i")?;
+    write_swizzle_tests_scalar("i16", "i16")?;
+    write_swizzle_tests_scalar("i8", "i8")?;
+
+    write_swizzle_tests_scalar("u64", "u64")?;
+    write_swizzle_tests_scalar("u32", "u")?;
+    write_swizzle_tests_scalar("u16", "u16")?;
+    write_swizzle_tests_scalar("u8", "u8")?;
+
+    Ok(())
+}
+
+fn main() -> Result<()> {
+    // Change into `./codegen` dir for convenience to the user
+    std::env::set_current_dir(env!("CARGO_MANIFEST_DIR"))?;
+
+    write_swizzle_tests()?;
+    Ok(())
+}


Test patch:
diff --git a/tests/swizzles_f64.rs b/tests/swizzles_f64.rs
index bcc0649..8513d78 100644
--- a/tests/swizzles_f64.rs
+++ b/tests/swizzles_f64.rs
@@ -261,10 +261,6 @@ glam_test!(test_dvec4_swizzles, {
     assert_eq!(v.wwwy(), dvec4(4_f64, 4_f64, 4_f64, 2_f64));
     assert_eq!(v.wwwz(), dvec4(4_f64, 4_f64, 4_f64, 3_f64));
     assert_eq!(v.wwww(), dvec4(4_f64, 4_f64, 4_f64, 4_f64));
-});
-
-glam_test!(test_dvec4_swizzles_2, {
-    let v = dvec4(1_f64, 2_f64, 3_f64, 4_f64);
     assert_eq!(v.xxx(), dvec3(1_f64, 1_f64, 1_f64));
     assert_eq!(v.xxy(), dvec3(1_f64, 1_f64, 2_f64));
     assert_eq!(v.xxz(), dvec3(1_f64, 1_f64, 3_f64));