Skip to content

Implement TryFrom<OsString> for String#151822

Open
Kixunil wants to merge 1 commit intorust-lang:mainfrom
Kixunil:tryfrom-osstring-for-string
Open

Implement TryFrom<OsString> for String#151822
Kixunil wants to merge 1 commit intorust-lang:mainfrom
Kixunil:tryfrom-osstring-for-string

Conversation

@Kixunil
Copy link
Contributor

@Kixunil Kixunil commented Jan 29, 2026

This is draft because I was unable to compile locally, it will be probably broken for a few iterations.

Being able to generically convert strings can be beneficial for argument parsing code and similar situations especially in case of conditional conversions. The standard library already provided this converion, just not via a trait. This commit fills the gap by adding the impl.

This addition was approved in ACP 732. It was requested that FromUtf8Error should be made generic over the input and this commit obeys the request. However some challenges were encountered:

  • The fields were private and the type had no constructor - solved by making the fields public but unstable and #[doc(hidden)].
  • There is a method to perform lossy conversion and it looks like it should be provided for OsString as well - this is not yet resolved.
  • into_os_string method was requested but the types are in different crates - solved with #[rustc_allow_incoherent_impl].

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jan 29, 2026
@rust-log-analyzer

This comment has been minimized.

@Kixunil Kixunil force-pushed the tryfrom-osstring-for-string branch from 354b70a to dec3d5b Compare January 29, 2026 14:24
@rust-log-analyzer

This comment has been minimized.

@Kixunil Kixunil force-pushed the tryfrom-osstring-for-string branch 2 times, most recently from c73b8e0 to 68ea3bf Compare January 29, 2026 15:18
@rust-log-analyzer

This comment has been minimized.

@Kixunil Kixunil force-pushed the tryfrom-osstring-for-string branch from 68ea3bf to 2ff5e55 Compare January 29, 2026 15:46
@rust-log-analyzer

This comment has been minimized.

Being able to generically convert strings can be beneficial for argument
parsing code and similar situations especially in case of conditional
conversions. The standard library already provided this converion, just
not via a trait. This commit fills the gap by adding the impl.

This addition was approved in [ACP 732]. It was requested that
`FromUtf8Error` should be made generic over the input and this commit
obeys the request. However some challenges were encountered:

* The fields were private and the type had no constructor - solved by
  making the fields public but unstable and `#[doc(hidden)]`.
* There is a method to perform lossy conversion and it looks like it
  should be provided for `OsString` as well - this is not yet resolved.
* `into_os_string` method was requested but the types are in different
  crates - solved with `#[rustc_allow_incoherent_impl]`.

[ACP 732]: rust-lang/libs-team#732
@Kixunil Kixunil force-pushed the tryfrom-osstring-for-string branch from 2ff5e55 to 3a3227c Compare January 29, 2026 16:10
@Kixunil Kixunil marked this pull request as ready for review January 29, 2026 18:37
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 29, 2026
@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 29, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 29, 2026

r? @tgross35

rustbot has assigned @tgross35.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@tgross35
Copy link
Contributor

Kicking off a build for crater.

@bors try

@rust-bors

This comment has been minimized.

rust-bors bot pushed a commit that referenced this pull request Jan 30, 2026
Implement `TryFrom<OsString>` for `String`
@tgross35
Copy link
Contributor

Since you have already been thinking about the design in the ACP,

r? programmerjake

@rustbot rustbot assigned programmerjake and unassigned tgross35 Jan 30, 2026
@tgross35 tgross35 added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Jan 30, 2026
Comment on lines +638 to +654
/// Returns an [`OsStr`] slice that was attempted to convert to a `String`.
#[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_incoherent_impl]
pub fn as_os_str(&self) -> &OsStr {
&self.input[..]
}

/// Returns the [`OsString`] that was attempted to convert to a `String`.
///
/// This method is carefully constructed to avoid allocation. It will
/// consume the error, moving out the string, so that a copy of the string
/// does not need to be made.
#[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_incoherent_impl]
pub fn into_os_string(self) -> OsString {
self.input
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be added unstably (unlike traits). I think it will probably be fine to put up a stabilization PR shortly after this merges.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically trait impls can be unstable too (afaik they actually work now), but idk if it's standard practice to use that yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 that's news to me! I think we may as well try it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see https://rustc-dev-guide.rust-lang.org/stability.html#unstable_feature_bound for docs.
You'll need to create a tracking issue, and replace the below NNN with that issue number.

#[unstable(feature = "tryfrom_os_string_for_string", issue = "NNN")]
#[unstable_feature_bound(tryfrom_os_string_for_string)]
impl TryFrom<OsString> for String {
    ...
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, you'll want to add #[must_use = ...] to those methods to match the methods on FromUtf8Error<Vec<u8>>


/// Attempts to convert an [`OsString`] into a [`String`].
///
/// This conversion does not allocate or copy memory.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does technically copy memory, just not the contents of the OsString.

The docs should probably be based on the docs of OsString::into_string:

/// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
///
/// On failure, ownership of the original `OsString` is returned.
///
/// # Examples
///
/// ```
/// use std::ffi::OsString;
///
/// let os_string = OsString::from("foo");
/// let string = os_string.into_string();
/// assert_eq!(string, Ok(String::from("foo")));
/// ```

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I copied it from some other method that says the same thing in such scenario. I will look into it.

Comment on lines +638 to +654
/// Returns an [`OsStr`] slice that was attempted to convert to a `String`.
#[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_incoherent_impl]
pub fn as_os_str(&self) -> &OsStr {
&self.input[..]
}

/// Returns the [`OsString`] that was attempted to convert to a `String`.
///
/// This method is carefully constructed to avoid allocation. It will
/// consume the error, moving out the string, so that a copy of the string
/// does not need to be made.
#[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_incoherent_impl]
pub fn into_os_string(self) -> OsString {
self.input
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, you'll want to add #[must_use = ...] to those methods to match the methods on FromUtf8Error<Vec<u8>>

@programmerjake
Copy link
Member

So, as mentioned, please change the API to #[unstable(...)] and create a tracking issue.

@rustbot author

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 30, 2026
@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 30, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 30, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 30, 2026

☀️ Try build successful (CI)
Build commit: e5b0618 (e5b0618d996a6a3941e423fd3e170737b8dbdc92, parent: 36e2b8a3a7aad93f8a92db6d254b746aa94ed6da)

@tgross35
Copy link
Contributor

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-151822 created and queued.
🤖 Automatically detected try build e5b0618
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 30, 2026
@craterbot
Copy link
Collaborator

🚧 Experiment pr-151822 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-151822 is completed!
📊 2 regressed and 3 fixed (800034 total)
📊 2203 spurious results on the retry-regressed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-151822/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Feb 6, 2026
@programmerjake
Copy link
Member

looks like nothing significant changed in the crater run.

so I'm changing this back to waiting on the author: #151822 (comment)

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants