The trait bound `Arc<i32>: Copy` is not satisfied

I'm using const generics as parameter to illustrate an array type:

struct Foo<const I: usize> {
    i: [Option<Arc<i32>>;I],
}

impl<const I: usize> Foo<I> {
    fn get() -> Self {
        Foo {
            i: [None;I]
        }
    }
}

But the code will not compile, it said that Arc<i32> needs to implement copy trait:

error[E0277]: the trait bound `Arc<i32>: Copy` is not satisfied
  --> src/main.rs:10:17
   |
10 |             i: [None;I]
   |                 ^^^^ the trait `Copy` is not implemented for `Arc<i32>`
   |
   = note: required for `Option<Arc<i32>>` to implement `Copy`
   = note: the `Copy` trait is required because this value will be copied for each element of the array

I seem to know why it needs copy trait for an array initialization, but in my case I only initiate with None, so is there any chance my code could work?

I think you should be able to use std::array::from_fn to do what you need

4 Likes

Awesome! It works.

Another alternative is to use a constant: Array expressions allow initialization with the value of a const item, so this will work:

impl<const I: usize> Foo<I> {
    fn get() -> Self {
        const NONE: Option<Arc<i32>> = None;
        Foo {
            i: [NONE; I]
        }
    }
}

eventually, this could be simplified when we get const { … } expressions, to

impl<const I: usize> Foo<I> {
    fn get() -> Self {
        Foo {
            i: [const { None }; I],
        }
    }
}

I suppose one (main) advantage of this over array::from_fn is that this allows you to make fn get() itself a const fn, too. Other than that, array::from_fn is probably more readable (than the approach using a const item) and (I assume) shouldn’t make a difference in terms of performance.

6 Likes

It seems that inline_const is an unstable feature and I never know it before, learns every day :smile: I like this solution because it allows get function to be a const function.

Hopefully soon™! It's in p-FCP and the two concerns that were raised have been resolved: https://github.com/rust-lang/rust/pull/104087#issuecomment-1360034741

So maybe it'll make Rust 1.69.0 on 4/20.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.