Auto array to slice


#1

Regarding the “making Rust simpler to use”, is it a good idea to accept code like this too?

fn foo(arr: &[i32]) {}
fn main() {
    foo([1, 2, 3, 4]);
}

#2

I could see the following getting accepted, but casting a non-reference [T; 4] to &[T] wouldn’t be acceptable in my opinion.

fn foo(arr: &[i32]) {}
fn main() {
    foo(&[1, 2, 3, 4]);
}

#3

Your code is currently accepted.

What’s bad about it?


#4

The auto-ref there is confusing to me. We don’t accept it for primitives, for example (see below). I think that being explicit about whether ownership is given up at a function call is good, since it avoids having to learn and reason about those concepts based on inference. Being explicit about such a crucial concept as ownership, especially in this case, makes sense to me, though I’d be open to arguments against this. However, I think that if we allow the autoref that you propose to work, we’d need to allow autoref in general for consistency’s sake.

fn test(x: &i32) {}
test(100); // error: expected &i32
test(&100); // this is fine

#5

I think your arguments are reasonable, thank you. Finding the right balance between un-cluttering Rust and several other needs (clarity, uniformity, explicitness, code reliability, and so on) is not easy.


#6

I had the same idea independently an hour ago: https://github.com/rust-lang/rfcs/issues/1984

since we have autoref for method calls, I don’t see why we can’t have a limited version of autoref in argument position.

the & in test(&100) is just noise. It gets worse with test(&(50 + i)) and similar operations


#7

You can use:

fn foo<T: AsRef<[i32]>>(arr: T) {
    let arr = arr.as_ref();
}

and it will accept arrays, slices, vectors, etc.


#8

This sounds like https://internals.rust-lang.org/t/ergonomics-initiative-discussion-allowing-owned-values-where-references-are-expected/5161.