# ReadBuf as part of Rust edition 2021

**URL:** <https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256>\
**Category:** libs\
**Created:** [March 13, 2021, 5:26am UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256 "2021-03-13T05:26:35Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Qwaz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/qwaz/32/7160_2.png) [@Qwaz](https://internals.rust-lang.org/u/Qwaz)\
**Post date:** [March 13, 2021, 5:26am UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/1 "2021-03-13T05:26:35Z")

</div>

Passing an uninitialized buffer to generic `Read` implementation is one of the most common soundness bugs in the Rust ecosystem (e.g., [RUSTSEC-2021-0015](https://rustsec.org/advisories/RUSTSEC-2021-0015.html), [RUSTSEC-2021-0029](https://rustsec.org/advisories/RUSTSEC-2021-0029.html), [gfx#3567](https://github.com/gfx-rs/gfx/issues/3567)). Unfortunately, initializing the buffer often leads to performance degradation, and there is currently no way to use generic `Read` without initialization cost in stable Rust.

[RFC 2930](https://github.com/rust-lang/rfcs/blob/master/text/2930-read-buf.md) provides a solution to this issue. It adds `ReadBuf` type and related APIs to `Read` trait, which allows safe management of uninitialized buffer. This RFC has been merged, but there is no implementation available yet.

What I would like to suggest is to prioritize, implement, and _advertise_ RFC 2930 as part of edition 2021. Technically `ReadBuf` is not a breaking change, but as noted in the RFC, `ReadBuf` introduces nontrivial amount of complexity to one of the standard library's core traits. Thus, advertising it as a change introduced in a new edition will help people learn and adopt new APIs, because people are more willing to accept larger changes at the edition boundary.

Additionally, raising the awareness of `ReadBuf` would help resolve longstanding misconception about uninitialized buffers in Rust. Although incorrect use of an uninitialized buffer can lead to observable memory safety errors ([#1](https://github.com/rust-lang/rfcs/blob/master/text/2930-read-buf.md#but-how-bad-are-undefined-values-really), [#2](https://www.ralfj.de/blog/2019/07/14/uninit.html)), the impact of using an uninitialized buffer is often overlooked. I've seen several soundness bugs that follow the similar pattern of uninitialized `read()` (e.g., [RUSTSEC-2020-0123](https://rustsec.org/advisories/RUSTSEC-2020-0123.html), [glium#1907](https://github.com/glium/glium/issues/1907), [claxon#26](https://github.com/ruuda/claxon/issues/26)). When implemented, `ReadBuf` could be a solid example that explains an uninitialized buffer cannot be passed to an API that is not expecting it, which I believe helps prevent the occurrence of similar soundness bugs in the future.

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbrubeck/32/174_2.png) [@mbrubeck](https://internals.rust-lang.org/u/mbrubeck)\
**Post date:** [March 13, 2021, 6:33am UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/2 "2021-03-13T06:33:33Z")

</div>

Welcome back to the Internals forum, @Qwaz!

I just want to point out, in case anyone isn't already familiar, that @Qwaz and the other members of the Rust group at [SSLab](https://gts3.org/) are responsible for identifying nearly half of all the vulnerabilities reported to [rustsec.org](http://rustsec.org) in recent months. They probably know more than anyone else about which Rust features lead to the most security bugs in the wild.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [March 13, 2021, 7:00am UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/3 "2021-03-13T07:00:35Z")

</div>

I'll take what @mbrubeck said at face value, and say that if you believe this is worth prioritizing, it probably should be. There's a fair amount of time until Rust 2021 gets released (October IIRC), so something like this certainly has time to land at the same time.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [March 13, 2021, 4:56pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/4 "2021-03-13T16:56:22Z")

</div>

Not to throw a damper on the accepted RFC, but I'm a little worried about possible confusion between `ReadBuf` (a partially uninitialized buffer to read into) and [`BufRead`](https://doc.rust-lang.org/stable/std/io/trait.BufRead.html) (a read that uses reader managed buffers rather than caller managed buffers). The latter is potentially [going to be important for async](https://without.boats/blog/io-uring/), so having these share such similar names is... unfortunate.

I do support prioritization of this functionality, though!

---

<div class="post-metadata">

**Author:** ![Aloso](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/aloso/32/5039_2.png) [@Aloso](https://internals.rust-lang.org/u/Aloso)\
**Post date:** [March 13, 2021, 11:55pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/5 "2021-03-13T23:55:52Z")

</div>

To quote [RFC 3085](https://github.com/rust-lang/rfcs/pull/3085):

> The expectation is that the 2021 Edition will _not_ be marketed as an "all encompassing event" in the same way as the 2018 Edition.

The reason for this is that many people were confused why features were advertised as part of the 2018 edition, even though they were available in edition 2015 as well.

I think it's better to clearly distinguish between an _edition_ and the _Rust version_ in which the edition was introduced. A marketing push does more harm than good if it is dishonest about the things it advertises. I believe this is the main reason why RFC 2052 ("Edition 2021 and beyond") was rejected.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [March 14, 2021, 12:45am UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/6 "2021-03-14T00:45:44Z")

</div>

(why not just call it a `Buffer` or `UninitBuffer`?)

---

<div class="post-metadata">

**Author:** ![Qwaz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/qwaz/32/7160_2.png) [@Qwaz](https://internals.rust-lang.org/u/Qwaz)\
**Post date:** [March 14, 2021, 4:22am UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/7 "2021-03-14T04:22:31Z")

</div>

One goal of edition 2018 was wrapping significant updates and advertising it to users who are not paying close attention to Rust. That is exactly what I thought is needed for `ReadBuf` update, and why I suggested to include `ReadBuf` in edition 2021.

Thanks for pointing out that the Rust core team is inclined towards taking a different approach this time. The ["Rallying point" editions](https://github.com/nikomatsakis/rfcs/blob/edition-2021-or-bust/text/0000-edition-2021.md#rallying-point-editions) section of the RFC says:

> There is a certain segment of potential Rust users that may be interested in Rust but not interested enough to follow along with every release and track what has changed. For those users, a blog post that lays out all the exciting things that have happened since Rust 2018 could be enough to persuade them to give Rust a try. We can address this by releasing a retrospective that goes over the last few years of progress. We don't have to tie this retrospective to the edition, however, and as such it is not described in this RFC.

What I probably want is then to include `ReadBuf` as part of this retrospective post so that it gets necessary attention.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [March 14, 2021, 4:34pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/8 "2021-03-14T16:34:18Z")

</div>

I would love to see `ReadBuf` stabilized, and then mentioned in several places.

> <https://github.com/rust-lang/rust/issues/78485>
>
> This is a tracking issue for the RFC "2930" (rust-lang/rfcs#2930).
> The feature gate for the issue is #!\[feature(read\_buf)\].
> About tracking issues
> Tracking issues are...

---

<div class="post-metadata">

**Author:** ![djc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/djc/32/1592_2.png) [@djc](https://internals.rust-lang.org/u/djc)\
**Post date:** [March 15, 2021, 9:59pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/9 "2021-03-15T21:59:31Z")

</div>

I'm pretty excited about the improvements that `ReadBuf` can bring, but I'm also still wondering if can slightly generalize is to close another safety gap.

My observation is that `Vec<T>` is analogous to a `ReadBuf` in that it consists of a filled part (`len`) and an uninitialized part (`capacity`). However, if we wrap the `Vec`'s backing byte array in a `ReadBuf`, we will still need to unsafely set the len for `Vec`. Would it be worth it to give the `ReadBuf` type some kind of type parameter that will allow it to update the backing store when the `ReadBuf` itself is dropped?

Or, going even further, should we extend `ReadBuf` to support types of data other than `u8`, especially as we see the work on safe transmutes come to fruition?

---

<div class="post-metadata">

**Author:** ![Johannesd3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/johannesd3/32/7549_2.png) [@Johannesd3](https://internals.rust-lang.org/u/Johannesd3)\
**Post date:** [March 15, 2021, 10:14pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/10 "2021-03-15T22:14:21Z")

</div>

I was also thinking about it, but it's not really analogous.

- ReadBuf: Filled -\> Initialized -\> Uninitialized
- Vec: Filled = Initialized -\> Uninitialized (-\> Unallocated)

I think connecting those two will just make it unnecessarily complicated.

On the other hand, I like the idea of a generic `ReadBuf`. For example, audio samples are often stored as 16- or 32-bit numbers.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [March 15, 2021, 10:32pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/11 "2021-03-15T22:32:24Z")

</div>

I don't think we should make ReadBuf typed. We could always introduce a generic version in the future if someone proposes and implements that, and we could make ReadBuf a type alias for it. But that shouldn't prevent us from stabilizing the current version, which has an established use case and implementation.

---

<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:** [June 13, 2021, 10:32pm UTC](https://internals.rust-lang.org/t/readbuf-as-part-of-rust-edition-2021/14256/12 "2021-06-13T22:32:46Z")

</div>

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