# Add \`impl\<T\> AsRef\<\[T\]\> for T\`

**URL:** <https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257>\
**Category:** libs\
**Created:** [July 26, 2024, 1:02pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257 "2024-07-26T13:02:20Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![pubfnbar](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pubfnbar/32/7007_2.png) [@pubfnbar](https://internals.rust-lang.org/u/pubfnbar)\
**Post date:** [July 26, 2024, 1:02pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/1 "2024-07-26T13:02:20Z")

</div>

Could we add the following blanket implementations to `std::convert`?

```rust
impl<T> AsRef<[T]> for T {
    fn as_ref(&self) -> &[T] {
        unsafe { std::slice::from_raw_parts(self, 1) }
        // UPDATE: or preferably the safe version:
        // std::slice::from_ref(self)
    }
}

impl<T> AsMut<[T]> for T {
    fn as_mut(&mut self) -> &mut [T] {
        unsafe { std::slice::from_raw_parts_mut(self, 1) }
        // UPDATE: or preferably the safe version:
        // std::slice::from_mut(self)
    }
}

```

This addition would improve ergonomics (and maybe even performance for large types) when calling a function that takes an `AsRef` by passing a single `value` instead of having to pass `[value]`. For example:

```rust
fn print_each<T: AsRef<[i32]>>(values: T) {
    for value in values.as_ref() {
        println!("{value}");
    }
}

fn print_some_values() {
    // Currently you'd have to write `print_each([42])`
    print_each(42);
    print_each([11, 22, 33]);
}

```

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [July 26, 2024, 1:28pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/2 "2024-07-26T13:28:03Z")

</div>

If anything, it would only reduce readability IMO. It doesn't affect performance as `T` and `[T; 1]` are the exact same size and I think passed the same way in the Rust ABI.

---

<div class="post-metadata">

**Author:** ![pubfnbar](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pubfnbar/32/7007_2.png) [@pubfnbar](https://internals.rust-lang.org/u/pubfnbar)\
**Post date:** [July 26, 2024, 2:31pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/3 "2024-07-26T14:31:41Z")

</div>

Perhaps a better example to demonstrate the (in my opinion) improved ergonomics:

```rust
fn foo(values: &[i32], value: i32) {
    let mut x = MyCollection::from(values);
    
    // Instead of `MyCollection::from([value])`, we _can_ write:
    let y = MyCollection::from(value);

    x.append(values);

    // Instead of `x.append([value])`, we _can_ write:
    x.append(value);
}

```

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [July 26, 2024, 2:42pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/4 "2024-07-26T14:42:58Z")

</div>

Is `let t = [t];` optimized to a no-op? I tried in the playground, but Assembly generation isn't working and I can't read HIR/MIR/LLVM IR well enough to determine that it is optimized to a no-op.

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [July 26, 2024, 3:02pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/5 "2024-07-26T15:02:51Z")

</div>

[rust.godbolt.com](http://rust.godbolt.com) is very much recommended for assembly inspection.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [July 26, 2024, 4:30pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/6 "2024-07-26T16:30:54Z")

</div>

Aside, [`slice::from_ref`](https://doc.rust-lang.org/stable/std/slice/fn.from_ref.html) and [`from_mut`](https://doc.rust-lang.org/stable/std/slice/fn.from_mut.html) do these conversions safely.

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [July 26, 2024, 6:09pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/7 "2024-07-26T18:09:54Z")

</div>

Ah, neat. [The underlying impl](https://doc.rust-lang.org/1.80.0/src/core/array/mod.rs.html#116).

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [July 26, 2024, 6:36pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/8 "2024-07-26T18:36:32Z")

</div>

> [@pubfnbar](#):
>
> Could we add the following blanket implementations to `std::convert`?

To answer this directly: No, it's a breaking change since [I may already have `impl AsRef<[MyStruct]> for MyStruct`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=385871ef552ea383f54b38f9c0641b9e) and the blanket implementation would conflict with that.

[Adding any blanket impl for an existing trait is a major breaking change.](https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html#teaching-users)

---

<div class="post-metadata">

**Author:** ![pubfnbar](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pubfnbar/32/7007_2.png) [@pubfnbar](https://internals.rust-lang.org/u/pubfnbar)\
**Post date:** [July 26, 2024, 6:54pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/9 "2024-07-26T18:54:12Z")

</div>

Theoretically, would a new Rust edition be allowed to make a breaking change such as this one?

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [July 26, 2024, 7:47pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/10 "2024-07-26T19:47:31Z")

</div>

Crates have to interoperate across editions, so technically no, editions don't help with the blanket implementation case.

That said, one can dream up approaches that aren't technically a blanket implementation, like structs defined in edition 20XX automatically have `AsRef<[Self]>` derived unless you opt out. There would have to be an opt-out, because otherwise

- [it breaks use cases that rely on local negative reasoning in coherence](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5c3b91833bde749ff583bb20b87a02f9)\[1\]
- it would be ecosystem-splitting\[2\] due to existing implementations that don't match the derived implementation (such as the playground in my other comment)

(You could then talk about deeper layers of complexity; "It's automatically derived unless you define it"\[3\] would help with the second bullet but not the first one, so now you need to somehow detect that case too..... but even by this point we're getting into behavior which is IMO overly complicated and too fragile to be tenable.)

* * *

One could also have a conversation: If the likely outcome or perhaps even explicit goal is to make one particular implementation so omnipresent that the ecosystem expects it, and thus all crates that are exceptions get pressured to change or be abandoned -- is that morally different from actually making the breaking change or ecosystem split, which you promised to never do?

* * *

1. this also means it would _have_ to be on an edition 

2. some crates would choose or be forced to stay on an old edition 

3. aping specialization

---

<div class="post-metadata">

**Author:** ![pubfnbar](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pubfnbar/32/7007_2.png) [@pubfnbar](https://internals.rust-lang.org/u/pubfnbar)\
**Post date:** [July 26, 2024, 8:07pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/11 "2024-07-26T20:07:37Z")

</div>

Thank you for a great explanation.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 24, 2024, 8:07pm UTC](https://internals.rust-lang.org/t/add-impl-t-asref-t-for-t/21257/12 "2024-10-24T20:07:38Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
