Generic that accepts only owned type

Is there any way I can force a struct to only accept owned data types(no references)?

For example:

struct MyStruct<T> 
    where T: Owned
{
    partitions: Vec<T>
}
...
MyStruct<i32> // valid
MyStruct<&i32> // invalid

Probably not, but why do you need this? Perhaps this is not the root problem you're trying to solve.

You can use lifetime bound T: 'static. It won't forbid the references at all, but will restrict them to the ones which can live until the end of program.

2 Likes

At a logical level, the data belongs to the structure and should not allow access to anybody outside its internal API.

At an implementation level I do have the problem which I think is tied to this: that using the threadpool::ThreadPool#execute force me to have a 'static lifetime on the clojure:

fn foo(self, f: ...)
{
        let (tx, rx) = channel();

        let n_jobs = self.partitions.len();

        let it: Iter<Partition<T>> = self.partitions.iter();

        for p in it {
            let tx = tx.clone();

            self.thread_pool.execute(move || {
                tx.send(p.map(f));
            });
        }


        let partitions = rx.iter().take(n_jobs).collect();

        ....
    }

Yields:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> 
   |
42 |         let it: Iter<Partition<T>> = self.partitions.iter();
   |                                                      ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 34:5...
  --> 
   |
34 | /     fn map<U>(&self, f: fn(&T) -> U) -> Rdd<'a, U>
35 | |     // todo check if send model is faster then barrier
36 | |         where U: Send
37 | |     {
...  |
55 | |         self.init_from_old(partitions)
56 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> mod.rs:42:38
   |
42 |         let it: Iter<Partition<T>> = self.partitions.iter();
   |                                      ^^^^^^^^^^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@mod.rs:47:38: 49:14 tx:std::sync::mpsc::Sender<smth::partition::Partition<U>>, p:&smth::partition::Partition<T>, f:for<'r> fn(&'r T) -> U]` will meet its required lifetime bounds
  --> mod.rs:47:30
   |
47 |             self.thread_pool.execute(move || {
   |                              ^^^^^^^

Reference-counted smart pointers such as std::rc::Rc or std::sync::Arc are owned data types but accessible outside the owner of single Rc or Arc (even mutable access would be available with RefCell or Mutex), so I think restricting to owned types is not what you really want.

3 Likes