Which exact types? If we required specific types, weād need some way to inform the compiler of them, and the specificity requirement would imply that thereās exactly one type that can be used? If so, that would impose the requirement that thereās only one definition of SIMD types in a given tree of dependencies, and I really really donāt want that requirement. (For one, I personally donāt expect to get everything right first time, so itād be very good if people are free to experiment themselves without āaccidentalā/arbitrary restrictions.)
Iām moderately concerned that introducing a vein of ārelaxedā typing into the compiler will leave the door open for abuse/crazy tricks, but Iām unsure. However it seems quite restricted, so itās not clear to me that one can do anything even slightly useful with it. Note, in practice, people using SIMD wonāt need to worry about this at all: libraries will define things to ensure type safety (even at the intrinsic level).
NB. for the platform specific intrinsics we can/will require that they arenāt generic, so can type-check them in the type checker, properly (properly == answering is this a SIMD type of the appropriate length with the appropriate element type?). Hence, this discussion is basically the difference between being able to write fn simd_shuffle2<T, U>(v: T, w: T, ...) -> Simd2<U> and having the option to impose type safety (which is what will happen in practice), or being forced to have scheme by which the compiler can be totally assured that things will work. This would either require writing separate shuffle/comparison intrinsics for every concrete SIMD type, or would require compiler-known traits (like #[simd_primitive_trait], but also at least one more, I think) with some compulsory associated types and so on.
#[simd_primitive_trait]
trait SimdPrim {
type Bool: SimdPrim;
}
#[simd_vector_trait]
trait SimdVector {
type Elem: SimdPrim;
type Bool: SimdVector<Elem = Self::Elem::Bool>;
}
#[repr(simd)]
struct Simd2<T: SimdPrim>(T, T);
impl<T: SimdPrim> SimdVector for Simd2<T> {
type Elem = T;
type Bool = Simd2<T::Bool>;
}
extern {
fn simd_shuffle2<T: SimdVector>(v: T, w: T, i0: u32, i1: u32) -> Simd2<T::Elem>;
// ...
fn simd_lt<T: SimdVector>(v: T, w: T) -> T::Bool;
// ...
}
Weād need to have careful restrictions about how the implementations of SimdPrim and SimdVector can work, and especially around generic types. It seems very complicated, and Iām not sure itās worth it.