Initializing array of Option<T> using [None; n] syntax should not require std::marker::Copy for T

ac303b1
Opened by Deleted user at 2023-03-07 06:05:04

I am new to Rust so forgive me if this is a stupid assertion.

Currently if you have an array of Option<T> the std::marker::Copy must be on T when using the repeated element syntax while initializing the array.

Case and point:

let arr: [Option<String>; 5] = [None; 5];

Shouldn't the compiler know that it is only "copying" None and allow the assignment?

  1. For arrays less than 32 elements, you could workaround this using

    let arr: [Option<String>; 5] = Default::default();
    

    kennytm at 2017-09-23 19:00:44

  2. Shouldn't the compiler know that it is only "copying" None and allow the assignment?

    The type of None is Option<T>, though, not Option<T>::None. For discussions of having the variants of enums actually be types, see https://github.com/rust-lang/rfcs/pull/1450

    scottmcm at 2017-09-24 04:28:07

  3. It should be able to determine if the expression is const, though, which has no side-effects and could potentially be copied over the array. For many people it's confusing and frustrating that [expr; n] isn't just a shorthand for [<expr repeated n times>]. But of course it's a (logically) breaking change now, like if expr results in a Copy type but has side-effects.

    Austin Bonander at 2017-09-24 19:51:24

  4. For arrays of any length you can use this workaround since Rust 1.38:

    const INIT: Option<String> = None;
    let arr: [Option<String>; 1000] = [INIT; 1000];
    

    Luca Casonato at 2021-11-13 00:50:23

  5. If https://github.com/rust-lang/rust/pull/104087 is merged then this can be closed.

    Jubilee at 2023-03-07 05:53:06

  6. There's an argument that, since const items work without needing the const{…} wrapper, that None just Just Work™ too as it's essentially a const item.

    (Assuming we get generic consts that'd be more direct.)

    scottmcm at 2023-03-07 06:05:04