feat(util): const-ify the tokio-util builders#7810
feat(util): const-ify the tokio-util builders#7810BastiDood wants to merge 3 commits intotokio-rs:masterfrom
const-ify the tokio-util builders#7810Conversation
c50f43b to
456a02e
Compare
| /// assert_eq!(codec.max_length(), 256); | ||
| /// ``` | ||
| pub fn max_length(&self) -> usize { | ||
| pub const fn max_length(&self) -> usize { |
There was a problem hiding this comment.
Why would you want to make a method const when its constructor is not const? (The same applies to several other files.)
There was a problem hiding this comment.
Fair point; I figured it as mostly a matter of forwards-compatibility when Rust eventually stabilizes wider const support elsewhere. I dream of the day Rust gets powerful const evaluation like Zig's comptime and C++'s constexpr.
For example: some VecDeque methods can be const, but somehow hasn't been const-ified. When cases like that eventually resolve, we can trivially upgrade the constructors to have end-to-end const support.
Note
For this example in particular, though, I just missed adding a const to the constructor. I've amended the commit now. Thanks for pointing it out!
There was a problem hiding this comment.
Making a method const when it cannot actually be used as such should be avoided if compatibility is in mind, as it prevents us from changing its implementation to something incompatible with const in the future.
There was a problem hiding this comment.
That makes sense. I've reverted the const methods without a const constructor in 79e6b1a. Let me know if I've missed anything. 🙇♂️
456a02e to
8e12228
Compare
taiki-e
left a comment
There was a problem hiding this comment.
I suspect it should be possible to make getter methods that return the mutable reference const as well.
|
|
||
| /// Obtain a reference to the handle inside this `TokioContext`. | ||
| pub fn handle(&self) -> &Handle { | ||
| pub const fn handle(&self) -> &Handle { |
There was a problem hiding this comment.
This was a missed const constructor actually. We can safely add pub const fn new. The fix was lumped in with 79e6b1a.
| /// # pub fn main() {} | ||
| /// ``` | ||
| pub fn new() -> Builder { | ||
| pub const fn new() -> Builder { |
There was a problem hiding this comment.
I think new_codec and new_framed can also be const.
There was a problem hiding this comment.
I hoped so too, but unfortunately, they can't because the FramedImpl instantiates RWFrames as its internal state. Since RWFrames invokes BytesMut::with_capacity in its Default implementation, the overall constructor is now non-const (at least until const Default gets stabilized).
Note
Using BytesMut::new won't save us here because it is also non-const by virtue of invoking BytesMut::with_capacity(0) internally.
There was a problem hiding this comment.
Let me clarify: only new_codec can be const-ified (see ed6a13a), but new_framed can't because of the aforementioned BytesMut::with_capacity limitation.
|
This constifies a lot of methods. Can you explain exactly which ones require a higher MSRV? I can see some of them that I'm certain do not require it. In general, I don't think making a few methods in tokio-util const is a very strong reason to bump the MSRV. |
These are mostly the builder methods that set values in mutable contexts (behind
The rest of them are MSRV-compatible
That's understandable. Though, just to give some context: it was not my intention to bump the MSRV just for the sake of fulfilling this feature in isolation; I come at it hoping that the MSRV bump would unlock/spur new features and other refactors within Tokio. (Admittedly, I haven't looked into the specifics of what those exact "features and refactors" are aside from this PR, but benefiting from one year's worth of new Rust developments sounds like a lot of unlocked possibilities!) |
Caution
This PR is marked as a draft for now until the next MSRV bump happens. We need at least Rust 1.83 to support
constin mutable contexts.Motivation
While using the
tokio-utilcrate, I've found myself frequently constructing codec builders from scratch—so much so that I figured it would be mighty helpful if I can just hoist theBuilderconfiguration into astaticsomewhere (or alternatively, aconstcodec instance).But alas, none of the builders are marked as
const fnat the moment.Solution
This PR simply marks many of the builder methods as
const. For lack ofconstsupport as of the MSRV, someconst-ified methods required small refactors like:cmp::maxas explicitifblocksunwrap_oras explicitmatchblockstry_fromwith an explicit bounds check +as-castsconstcontexts.Note
When
const Dropandconst TryFromstabilizes, we can revert them back to their original formulation.