diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs
index d70e8a66b95..1f7ea854a93 100644
--- a/crates/core_simd/src/select.rs
+++ b/crates/core_simd/src/select.rs
@@ -1,3 +1,5 @@
+use crate::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount};
+
 mod sealed {
     pub trait Sealed {}
 }
@@ -9,79 +11,75 @@ pub trait Select<Mask>: Sealed {
     fn select(mask: Mask, true_values: Self, false_values: Self) -> Self;
 }
 
-macro_rules! impl_select {
-    {
-        $mask:ident ($bits_ty:ident): $($type:ident),*
-    } => {
-        $(
-        impl<const LANES: usize> Sealed for crate::$type<LANES> where crate::LaneCount<LANES>: crate::SupportedLaneCount {}
-        impl<const LANES: usize> Select<crate::$mask<LANES>> for crate::$type<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {
-            #[doc(hidden)]
-            #[inline]
-            fn select(mask: crate::$mask<LANES>, true_values: Self, false_values: Self) -> Self {
-                unsafe { crate::intrinsics::simd_select(mask.to_int(), true_values, false_values) }
-            }
-        }
-        )*
+impl<Element, const LANES: usize> Sealed for Simd<Element, LANES>
+where
+    Element: SimdElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+}
 
-        impl<const LANES: usize> Sealed for crate::$mask<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {}
-
-        impl<const LANES: usize> Select<Self> for crate::$mask<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {
-            #[doc(hidden)]
-            #[inline]
-            fn select(mask: Self, true_values: Self, false_values: Self) -> Self {
-                mask & true_values | !mask & false_values
-            }
-        }
-
-        impl<const LANES: usize> crate::$mask<LANES>
-        where
-            crate::LaneCount<LANES>: crate::SupportedLaneCount,
-        {
-            /// Choose lanes from two vectors.
-            ///
-            /// For each lane in the mask, choose the corresponding lane from `true_values` if
-            /// that lane mask is true, and `false_values` if that lane mask is false.
-            ///
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::{Mask32, SimdI32};
-            /// let a = SimdI32::from_array([0, 1, 2, 3]);
-            /// let b = SimdI32::from_array([4, 5, 6, 7]);
-            /// let mask = Mask32::from_array([true, false, false, true]);
-            /// let c = mask.select(a, b);
-            /// assert_eq!(c.to_array(), [0, 5, 6, 3]);
-            /// ```
-            ///
-            /// `select` can also be used on masks:
-            /// ```
-            /// # #![feature(portable_simd)]
-            /// # use core_simd::Mask32;
-            /// let a = Mask32::from_array([true, true, false, false]);
-            /// let b = Mask32::from_array([false, false, true, true]);
-            /// let mask = Mask32::from_array([true, false, false, true]);
-            /// let c = mask.select(a, b);
-            /// assert_eq!(c.to_array(), [true, false, true, false]);
-            /// ```
-            #[inline]
-            pub fn select<S: Select<Self>>(self, true_values: S, false_values: S) -> S {
-                S::select(self, true_values, false_values)
-            }
-        }
+impl<Element, const LANES: usize> Select<Mask<Element::Mask, LANES>> for Simd<Element, LANES>
+where
+    Element: SimdElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+    #[inline]
+    fn select(mask: Mask<Element::Mask, LANES>, true_values: Self, false_values: Self) -> Self {
+        unsafe { crate::intrinsics::simd_select(mask.to_int(), true_values, false_values) }
     }
 }
 
-impl_select! { Mask8 (SimdI8): SimdU8, SimdI8 }
-impl_select! { Mask16 (SimdI16): SimdU16, SimdI16 }
-impl_select! { Mask32 (SimdI32): SimdU32, SimdI32, SimdF32}
-impl_select! { Mask64 (SimdI64): SimdU64, SimdI64, SimdF64}
-impl_select! { MaskSize (SimdIsize): SimdUsize, SimdIsize }
+impl<Element, const LANES: usize> Sealed for Mask<Element, LANES>
+where
+    Element: MaskElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+}
+
+impl<Element, const LANES: usize> Select<Self> for Mask<Element, LANES>
+where
+    Element: MaskElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+    #[doc(hidden)]
+    #[inline]
+    fn select(mask: Self, true_values: Self, false_values: Self) -> Self {
+        mask & true_values | !mask & false_values
+    }
+}
+
+impl<Element, const LANES: usize> Mask<Element, LANES>
+where
+    Element: MaskElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+    /// Choose lanes from two vectors.
+    ///
+    /// For each lane in the mask, choose the corresponding lane from `true_values` if
+    /// that lane mask is true, and `false_values` if that lane mask is false.
+    ///
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::{Mask32, SimdI32};
+    /// let a = SimdI32::from_array([0, 1, 2, 3]);
+    /// let b = SimdI32::from_array([4, 5, 6, 7]);
+    /// let mask = Mask32::from_array([true, false, false, true]);
+    /// let c = mask.select(a, b);
+    /// assert_eq!(c.to_array(), [0, 5, 6, 3]);
+    /// ```
+    ///
+    /// `select` can also be used on masks:
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # use core_simd::Mask32;
+    /// let a = Mask32::from_array([true, true, false, false]);
+    /// let b = Mask32::from_array([false, false, true, true]);
+    /// let mask = Mask32::from_array([true, false, false, true]);
+    /// let c = mask.select(a, b);
+    /// assert_eq!(c.to_array(), [true, false, true, false]);
+    /// ```
+    #[inline]
+    pub fn select<S: Select<Self>>(self, true_values: S, false_values: S) -> S {
+        S::select(self, true_values, false_values)
+    }
+}
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index 9fb6d17d40a..03c2f93a9c2 100644
--- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs
@@ -9,7 +9,7 @@ pub use uint::*;
 // Vectors of pointers are not for public use at the current time.
 pub(crate) mod ptr;
 
-use crate::{LaneCount, SupportedLaneCount};
+use crate::{LaneCount, MaskElement, SupportedLaneCount};
 
 /// A SIMD vector of `LANES` elements of type `Element`.
 #[repr(simd)]
@@ -338,32 +338,32 @@ use sealed::Sealed;
 /// Marker trait for types that may be used as SIMD vector elements.
 pub unsafe trait SimdElement: Sealed + Copy {
     /// The mask element type corresponding to this element type.
-    type Mask: SimdElement;
+    type Mask: MaskElement;
 }
 
 impl Sealed for u8 {}
 unsafe impl SimdElement for u8 {
-    type Mask = u8;
+    type Mask = i8;
 }
 
 impl Sealed for u16 {}
 unsafe impl SimdElement for u16 {
-    type Mask = u16;
+    type Mask = i16;
 }
 
 impl Sealed for u32 {}
 unsafe impl SimdElement for u32 {
-    type Mask = u32;
+    type Mask = i32;
 }
 
 impl Sealed for u64 {}
 unsafe impl SimdElement for u64 {
-    type Mask = u64;
+    type Mask = i64;
 }
 
 impl Sealed for usize {}
 unsafe impl SimdElement for usize {
-    type Mask = usize;
+    type Mask = isize;
 }
 
 impl Sealed for i8 {}