Repository: arrayfire/arrayfire-rust (language: rust)

Issue:
Add trait bounds for indexing to allow valid types that match upstream Checks



Discussion / hints:

Fix patch:
diff --git a/src/core/index.rs b/src/core/index.rs
index a67d86d7a..641e9735b 100644
--- a/src/core/index.rs
+++ b/src/core/index.rs
@@ -2,7 +2,7 @@ use super::array::Array;
 use super::defines::AfError;
 use super::error::HANDLE_ERROR;
 use super::seq::Seq;
-use super::util::{af_array, af_index_t, dim_t, HasAfEnum};
+use super::util::{af_array, af_index_t, dim_t, HasAfEnum, IndexableType};
 
 use libc::{c_double, c_int, c_uint};
 use std::default::Default;
@@ -142,7 +142,10 @@ pub trait Indexable {
 ///
 /// This is used in functions [index_gen](./fn.index_gen.html) and
 /// [assign_gen](./fn.assign_gen.html)
-impl<T: HasAfEnum> Indexable for Array<T> {
+impl<T> Indexable for Array<T>
+where
+    T: HasAfEnum + IndexableType,
+{
     fn set(&self, idxr: &mut Indexer, dim: u32, _is_batch: Option<bool>) {
         unsafe {
             let err_val = af_set_array_indexer(idxr.get(), self.get(), dim as dim_t);
@@ -155,9 +158,10 @@ impl<T: HasAfEnum> Indexable for Array<T> {
 ///
 /// This is used in functions [index_gen](./fn.index_gen.html) and
 /// [assign_gen](./fn.assign_gen.html)
-impl<T: Copy> Indexable for Seq<T>
+impl<T> Indexable for Seq<T>
 where
     c_double: From<T>,
+    T: Copy + IndexableType,
 {
     fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>) {
         unsafe {
@@ -256,10 +260,11 @@ impl<'object> Drop for Indexer<'object> {
 /// println!("a(seq(1, 3, 1), span)");
 /// print(&sub);
 /// ```
-pub fn index<IO, T: Copy>(input: &Array<IO>, seqs: &[Seq<T>]) -> Array<IO>
+pub fn index<IO, T>(input: &Array<IO>, seqs: &[Seq<T>]) -> Array<IO>
 where
     c_double: From<T>,
     IO: HasAfEnum,
+    T: Copy + HasAfEnum + IndexableType,
 {
     let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
     unsafe {
@@ -462,7 +467,7 @@ where
 pub fn lookup<T, I>(input: &Array<T>, indices: &Array<I>, seq_dim: i32) -> Array<T>
 where
     T: HasAfEnum,
-    I: HasAfEnum,
+    I: HasAfEnum + IndexableType,
 {
     unsafe {
         let mut temp: af_array = std::ptr::null_mut();
@@ -504,10 +509,11 @@ where
 /// // 1.0 1.0 1.0
 /// // 2.0 2.0 2.0
 /// ```
-pub fn assign_seq<T: Copy, I>(lhs: &mut Array<I>, seqs: &[Seq<T>], rhs: &Array<I>)
+pub fn assign_seq<T, I>(lhs: &mut Array<I>, seqs: &[Seq<T>], rhs: &Array<I>)
 where
     c_double: From<T>,
     I: HasAfEnum,
+    T: Copy + IndexableType,
 {
     let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
     unsafe {
@@ -632,9 +638,10 @@ struct SeqInternal {
 }
 
 impl SeqInternal {
-    fn from_seq<T: Copy>(s: &Seq<T>) -> Self
+    fn from_seq<T>(s: &Seq<T>) -> Self
     where
         c_double: From<T>,
+        T: Copy + IndexableType,
     {
         Self {
             begin: From::from(s.begin()),
diff --git a/src/core/seq.rs b/src/core/seq.rs
index 06c6c2eb7..4d6ec98c8 100644
--- a/src/core/seq.rs
+++ b/src/core/seq.rs
@@ -5,18 +5,23 @@ use serde::{Deserialize, Serialize};
 use std::default::Default;
 use std::fmt;
 
+use super::util::IndexableType;
+
 /// Sequences are used for indexing Arrays
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
 #[repr(C)]
-pub struct Seq<T> {
+pub struct Seq<T: IndexableType> {
     begin: T,
     end: T,
     step: T,
 }
 
 /// Default `Seq` spans all the elements along a dimension
-impl<T: One + Zero> Default for Seq<T> {
+impl<T> Default for Seq<T>
+where
+    T: One + Zero + IndexableType,
+{
     fn default() -> Self {
         Self {
             begin: One::one(),
@@ -27,7 +32,10 @@ impl<T: One + Zero> Default for Seq<T> {
 }
 
 /// Enables use of `Seq` with `{}` format in print statements
-impl<T: fmt::Display> fmt::Display for Seq<T> {
+impl<T> fmt::Display for Seq<T>
+where
+    T: fmt::Display + IndexableType,
+{
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(
             f,
@@ -37,7 +45,10 @@ impl<T: fmt::Display> fmt::Display for Seq<T> {
     }
 }
 
-impl<T: Copy> Seq<T> {
+impl<T> Seq<T>
+where
+    T: Copy + IndexableType,
+{
     /// Create a `Seq` that goes from `begin` to `end` at a step size of `step`
     pub fn new(begin: T, end: T, step: T) -> Self {
         Self { begin, end, step }
diff --git a/src/core/util.rs b/src/core/util.rs
index 2eff73f64..118948c42 100644
--- a/src/core/util.rs
+++ b/src/core/util.rs
@@ -827,3 +827,16 @@ impl Fromf64 for i16  { fn fromf64(value: f64) -> Self { value as Self }}
 impl Fromf64 for u8   { fn fromf64(value: f64) -> Self { value as Self }}
 #[rustfmt::skip]
 impl Fromf64 for bool { fn fromf64(value: f64) -> Self { value > 0.0   }}
+
+///Trait qualifier for the type of Arrays accepted by scan operations
+pub trait IndexableType {}
+
+impl IndexableType for f64 {}
+impl IndexableType for i64 {}
+impl IndexableType for u64 {}
+impl IndexableType for f32 {}
+impl IndexableType for i32 {}
+impl IndexableType for u32 {}
+impl IndexableType for i16 {}
+impl IndexableType for u16 {}
+impl IndexableType for u8 {}


Test patch: