-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Proposal
Problem statement
Right now, each "slice-like" method in the standard library has its own, dedicated methods to bypass Deref
and DerefMut
, which are named appropriately based upon the collection:
Vec::as_slice
andVec::as_mut_slice
String::as_str
andString::as_mut_str
However, for CString
, OsString
, and PathBuf
, there is an inconsistency where only the immutable versions of these methods are offered, and they are not usable in const context. However, OsString
and PathBuf
both implement DerefMut
, allowing mutable access via the trait:
CString::as_c_str
OsString::as_os_str
PathBuf::as_path
Motivating examples or use cases
All of these methods are useful for avoiding "deref closures" and type-ambiguous as_ref
calls, instead directly stating what type they return:
let x = String::new().as_ref(); // ambiguous
let x = Some(String::new()).map(AsRef::as_ref); // ambiguous
let x = Some(String::new()).map(String::as_str); // unambiguous
While it's questionable whether in-place editing of these string-like types is useful, it still can be done on mostly-ASCII text, and in particular, there are the methods str::make_ascii_lowercase
and str::make_ascii_uppercase
which could similarly be applied to CString
, OsString
, and PathBuf
.
Additionally, in code for tools like serde
, it's desirable to edit buffers in-place to, for example, replace escaped characters in-place, and additional bytes can be overwritten with placeholder bytes to keep the result still valid UTF-8. Even for CString
this is possible, and the addition of an &mut CStr
could be desirable to still indicate that it's valid to write to the buffer, but UB to write a NUL byte to it, instead of simply passing &mut [u8]
which does not convey this.
Solution sketch
Add the following methods:
CString::as_mut_c_str
OsString::as_mut_os_str
PathBuf::as_mut_path
And also allow those, plus the following methods, to be used in const context:
CString::as_c_str
OsString::as_os_str
PathBuf::as_path
And additionally, add a DerefMut
and associated AsMut<CStr>
and BorrowMut<CStr>
implementations for CString
and CStr
.
Alternatives
These methods are desirable to also forward in the Deref
and DerefMut
implementations of these methods, to make the code more clear. So, they will likely exist regardless, just as private methods or trait impls.
Links and related work
Since this was mostly just marking methods as const-unstable, I already filed a tracking issue here: rust-lang/rust#144288
But, this does include new methods technically, so, it should have an ACP. If the ACP is not accepted, the new methods will be removed, but presumably that tracking issue will still apply to making some methods const-unstable.
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.