the code below should be pretty self-explanatory.
anyway, here's the run down:
make a trait to extend the simd types (this should happen for any equivalently defined types, though i haven't tested that).
implement the trait for all f32 simd types.
define a generic function with the same trait bound as the extension trait.
the trait impl is now constrained to the function's generic parameter.
profit.
I tried this code:
#![feature(portable_simd)]
use core::simd::*;
trait SimdExt<const N: usize> where LaneCount<N>: SupportedLaneCount {
fn id(self) -> Self;
}
impl<const N: usize> SimdExt<N> for Simd<f32, N> where LaneCount<N>: SupportedLaneCount {
fn id(self) -> Self { self }
}
// these are all the same.
// just adding the where clause breaks it.
fn fine() {
let foo: f32x2 = f32x2::splat(0.0).id();
}
fn also_fine<const N: usize>() {
let foo: f32x2 = f32x2::splat(0.0).id();
}
// this one doesn't compile
fn oops<const N: usize>() where LaneCount<N>: SupportedLaneCount {
// the trait `SimdExt<N>` is not implemented for `std::simd::Simd<f32, 2_usize>`
let foo: f32x2 = f32x2::splat(0.0).id();
}
// this function demonstrates the "constrains" part (it compiles just fine).
fn fine_again<const N: usize>() where LaneCount<N>: SupportedLaneCount {
let foo: Simd<f32, N> = <Simd<f32, N>>::splat(0.0).id();
}
note that where LaneCount<N>: SupportedLaneCount, LaneCount<2_usize>: SupportedLaneCount doesn't work either.
it somehow "unifies everything trying to use that trait with N".
the code below should be pretty self-explanatory. anyway, here's the run down:
I tried this code:
I expected to see this happen: it compiles.
Instead, this happened: it doesn't compile.
Meta
rustc --version --verbose
:(i encountered this initially on 1.63.0 nightly, then upgraded hoping that it has been fixed in the latest version, which it wasn't)