Summary

Change array/slice patterns in the following ways:

  • Make them only match
    一致する、マッチさせる
    on arrays
    配列
    ([T; n] and [T]), not slices;
  • Make subslice matching
    一致する、マッチさせる
    yield
    産出する、出力する
    a value of type [T; n] or [T], not &[T] or &mut [T];
  • Allow
    許可する、可能にする
    multiple
    複数の
    mutable references
    参照
    to be made to different parts of the same array
    配列
    or slice in array
    配列
    patterns (resolving rust-lang/rust issue #8636).

Motivation

Before DST (and after the removal of ~[T]), there were only two types based

基となる、基底(の)
on [T]: &[T] and &mut [T]. With DST, we can have many more types based
基となる、基底(の)
on [T], Box<[T]> in particular, but theoretically any pointer type around a [T] could be used. However, array
配列
patterns still match
一致する、マッチさせる
on &[T], &mut [T], and [T; n] only, meaning that to match
一致する、マッチさせる
on a Box<[T]>, one must first convert
変換する
it to a slice, which disallows
許可しない
moves. This may prove to significantly
著しく
limit the amount of useful code that can be written using array
配列
patterns.

Another problem with today’s array

配列
patterns is in subslice matching,
一致する、マッチさせる
which specifies
特定する、指定する、規定する
that the rest of a slice not matched
一致する、マッチさせる
on already in the pattern should be put into a variable:
変数、ストレージ

#![allow(unused)] fn main() { let foo = [1i, 2, 3]; match foo { [head, tail..] => { assert_eq!(head, 1); assert_eq!(tail, &[2, 3]); }, _ => {}, } }

This makes sense, but still has a few problems. In particular, tail is a &[int], even though the compiler can always assert that it will have a length of 2, so there is no way to treat

取り扱う
it like a fixed-length array.
配列
Also, all other bindings in array
配列
patterns are by-value, whereas bindings using subslice matching
一致する、マッチさせる
are by-reference (even though they don’t use ref). This can create confusing errors because of the fact that the .. syntax
文法
is the only way of taking
とる
a reference
参照
to something within a pattern without using the ref keyword.

Finally, the compiler currently complains when one tries to take

とる
multiple
複数の
mutable references
参照
to different values within the same array
配列
in a slice pattern:

#![allow(unused)] fn main() { let foo: &mut [int] = &mut [1, 2, 3]; match foo { [ref mut a, ref mut b] => ..., ... } }

This fails to compile, because the compiler thinks that this would allow

許可する、可能にする
multiple
複数の
mutable borrows to the same value (which is not the case).

Detailed design
設計(する)

  • Make array

    配列
    patterns match
    一致する、マッチさせる
    only on arrays
    配列
    ([T; n] and [T]). For example, the following code:

    #![allow(unused)] fn main() { let foo: &[u8] = &[1, 2, 3]; match foo { [a, b, c] => ..., ... } }

    Would have to be changed to this:

    #![allow(unused)] fn main() { let foo: &[u8] = &[1, 2, 3]; match foo { &[a, b, c] => ..., ... } }

    This change makes slice patterns mirror slice expressions

    much more closely.

  • Make subslice matching

    一致する、マッチさせる
    in array
    配列
    patterns yield
    産出する、出力する
    a value of type [T; n] (if the array
    配列
    is of fixed size) or [T] (if not). This means changing most code that looks like this:

    #![allow(unused)] fn main() { let foo: &[u8] = &[1, 2, 3]; match foo { [a, b, c..] => ..., ... } }

    To this:

    #![allow(unused)] fn main() { let foo: &[u8] = &[1, 2, 3]; match foo { &[a, b, ref c..] => ..., ... } }

    It should be noted that if a fixed-size array

    配列
    is matched
    一致する、マッチさせる
    on using subslice matching,
    一致する、マッチさせる
    and ref is used, the type of the binding will be &[T; n], not &[T].

  • Improve the compiler’s analysis

    解析
    of multiple
    複数の
    mutable references
    参照
    to the same value within array
    配列
    patterns. This would be done by allowing
    許可する、可能にする
    multiple
    複数の
    mutable references
    参照
    to different elements
    要素
    of the same array
    配列
    (including bindings from subslice matching):

    #![allow(unused)] fn main() { let foo: &mut [u8] = &mut [1, 2, 3, 4]; match foo { &[ref mut a, ref mut b, ref c, ref mut d..] => ..., ... } }

Drawbacks

  • This will break a non-negligible amount of code, requiring people to add &s and refs to their code.

  • The modifications to subslice matching

    一致する、マッチさせる
    will require ref or ref mut to be used in almost all cases. This could be seen as unnecessary.

Alternatives
代わりのもの、選択肢

  • Do a subset
    部分集合
    of this proposal; for example, the modifications to subslice matching
    一致する、マッチさせる
    in patterns could be removed.

Unresolved questions

  • What are the precise implications to the borrow checker of the change to multiple
    複数の
    mutable borrows in the same array
    配列
    pattern? Since it is a backwards-compatible change, it can be implemented
    実装する
    after 1.0 if it turns out to be difficult to implement.
    実装する