I trying to write a generic function called generic_concat which concatenates two arrays.
The implementation works without generics, but with generics, I get error: unconstrained generic constant
(Commented code does not work and causes the error)
#![allow(incomplete_features)]
#![feature(const_trait_impl)]
#![feature(generic_const_exprs)]
#![feature(const_mut_refs)]
use std::ptr;
#[inline(always)]
const unsafe fn ptr_slice_to_array_mut<'a, T, const N: usize>(slice: *mut [T]) -> &'a mut [T; N] {
&mut *(slice as *mut [T; N])
}
pub trait ArrayHelper<T, const N: usize> {
fn const_split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T; N - M]);
}
impl<T, const N: usize> const ArrayHelper<T, N> for [T; N]
{
#[inline]
fn const_split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T; N - M]) {
assert!(M <= N, "Bounds check failure in `[T; N]::split_array_mut'!");
let self_ptr = self.as_mut_ptr();
unsafe {
let left = ptr::slice_from_raw_parts_mut(self_ptr, M);
let right = ptr::slice_from_raw_parts_mut(self_ptr.add(M), N - M);
(ptr_slice_to_array_mut(left), ptr_slice_to_array_mut(right))
}
}
}
fn concat(a: &[u16; 128], b: &[u16; 128]) -> [u16; 256] {
let mut whole: [u16; 256] = [Default::default(); 256];
let (one, two) = whole.const_split_array_mut::<128>();
one.copy_from_slice(a);
two.copy_from_slice(b);
whole
}
pub fn it_works(a: [u16; 128], b: [u16; 128]) -> [u16; 256] {
concat(&a,&b)
}
// fn generic_concat<T: Copy + Default, const M: usize, const N: usize>(a: &[T; M], b: &[T; N]) -> [T; M+N] {
// let mut whole: [T; M+N] = [Default::default(); M+N];
// let (one, two) = whole.const_split_array_mut::<M>();
// one.copy_from_slice(a);
// two.copy_from_slice(b);
// whole
// }
// pub fn it_does_not_works(a: [u16; 128], b: [u16; 128]) -> [u16; 256] {
// generic_concat(&a,&b)
// }