How do I convert a list of Option<T> to a list of T when T cannot be copied?

In Rust, when you need a value, you generally want to move the elements or clone them.

Since move is more general, here it is, only two changes are necessary:

let nums: Vec<Uncopyable> = num_opts
    .into_iter()
//  ^~~~~~~~~~~~-------------- Consume vector, and iterate by value
    .filter(|x| x.is_some())
    .map(|x| x.unwrap())
//       ^~~------------------ Take by value
    .collect();

As llogiq points out, filter_map is specialized to filter out None already:

let nums: Vec<Uncopyable> = num_opts
    .into_iter()
//  ^~~~~~~~~~~~-------- Consume vector, and iterate by value
    .filter_map(|x| x)
//              ^~~----- Take by value
    .collect();

And then it works (consuming num_opts).


You don't need to copy the Uncopyable at all, if you are OK with using a Vec of references into the original Vec:

let nums: Vec<&Uncopyable> = num_opts.iter().filter_map(|x| x.as_ref()).collect();
//            ^ notice the & before Uncopyable?

This may not do the trick for you if you have to work with an API that requires &[Uncopyable]. In that case, use Matthieu M.'s solution which can be reduced to:

let nums: Vec<Uncopyable> = num_opts.into_iter().filter_map(|x| x).collect();