# (Pre-)RFC: Deprecate FromStr in favor of TryFrom\<&str\>

**URL:** https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331
**Category:** libs
**Created:** [May 12, 2020, 1:37pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331 "2020-05-12T13:37:42Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![malobre](https://avatars.discourse-cdn.com/v4/letter/m/96bed5/32.png) [@malobre](https://internals.rust-lang.org/u/malobre)
#### Post date: [May 12, 2020, 1:37pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/1 "2020-05-12T13:37:42Z")

</div>

_I rushed things a bit and prematurely created a [PR draft](https://github.com/rust-lang/rfcs/pull/2924). However this needs plenty of discussion so I'm creating this topic._

I feel like [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) — and consequently [`str::parse()`](https://doc.rust-lang.org/std/primitive.str.html#method.parse) — should be deprecated for the following reasons:

- [`TryFrom<&str>`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html) and [`From<&str>`](https://doc.rust-lang.org/std/convert/trait.From.html) virtually serves the same purpose as [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html)
- [`From<&str>`](https://doc.rust-lang.org/std/convert/trait.From.html) is much more idiomatic than [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) when the conversion is infallible:

```rust
struct Dummy(String);

impl std::str::FromStr for Dummy {
    type Err = core::convert::Infallible;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Dummy(s.to_owned()))
    }
}

//vs

impl From<&str> for Dummy {

    fn from(s: &str) -> Self {
        Dummy(s.to_owned())
    }
}

```

- [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) limits lifetimes in a way that prevents borrowing the passed string:

```rust
struct Dummy<'a>(&'a str);

// This doesn't compile
impl<'a> std::str::FromStr for Dummy<'a> {
    type Err = core::convert::Infallible;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Dummy(s))
    }
}

// This works
impl<'a> From<&'a str> for Dummy<'a> {

    fn from(s: &'a str) -> Self {
        Dummy(s)
    }
}

```

In the premature RFC I posted some concerns were raised about the churn created by this deprecation as [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) is widely used.

---

<div class="post-metadata">

### Author: ![burntsushi](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/burntsushi/32/279_2.png) [@burntsushi](https://internals.rust-lang.org/u/burntsushi)
#### Post date: [May 12, 2020, 1:51pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/2 "2020-05-12T13:51:39Z")

</div>

As I said on the PR, I am _strongly_ opposed to deprecating `parse`. It is ubiquitous in Rust code, and the churn it would cause is mind boggling, especially since it still works just fine. Its main problem is that it is a bit redundant. I personally don't feel like that rises to level of deprecating it.

Deprecating `FromStr` wouldn't be as bad as deprecating `parse` (if that's even possible), but it is still widely used, and as with `parse`, works just fine.

Overall, I'd like to see fewer deprecations in general, or at the very least, group them together so that they can all be addressed at once instead of spreading them out. But this particular deprecation doesn't seem well motivated IMO.

---

<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: [May 12, 2020, 2:00pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/3 "2020-05-12T14:00:44Z")

</div>

Perhaps we could start with a blanket `impl<T> FromStr for T where T: TryFrom<&str>`? We could keep `parse()` while at the same time guiding developers towards the more general `TryFrom` trait.

Personally I'm not as a big a fan of `parse()` since I feel it is pretty hard to understand how that works if you're encountering as a new user. By comparison, I feel like `try_into()` generalizes better and makes it slightly clearer what's going on under the covers.

---

<div class="post-metadata">

### Author: ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)
#### Post date: [May 12, 2020, 2:12pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/4 "2020-05-12T14:12:13Z")

</div>

I'm pretty sure that's potentially unsound because of lifetime specializations (any specialization only using a trait bound is potentially unsound). This means we can't expose it in a public api, because specialization is likely to change in significant ways to fix this soundness hole. (Also, we don't expose unstable features, like specialization in public apis, i.e. it should be possible to remove all uses of specialization without breaking anyone's builds).

---

<div class="post-metadata">

### Author: ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)
#### Post date: [May 13, 2020, 4:06am UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/5 "2020-05-13T04:06:21Z")

</div>

One thing I love about `parse()` is it's an inherent method and therefore you don't need any traits in scope to use it.

At present `TryInto` is not in the prelude, so using it for parsing means you have to import it every time.

> [@djc](#):
>
> Perhaps we could start with a blanket `impl<T> FromStr for T where T: TryFrom<&str>` ? We could keep `parse()`

This makes the most sense to me. I'd suggest not deprecating `parse` _at least_ until when/if `TryInto` winds up in a future (edition) prelude and can then be used as easily as `parse()` can today.

---

<div class="post-metadata">

### Author: ![kennytm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kennytm/32/161_2.png) [@kennytm](https://internals.rust-lang.org/u/kennytm)
#### Post date: [May 13, 2020, 6:22pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/6 "2020-05-13T18:22:23Z")

</div>

In the current libstd, `.try_into()` and `.parse()` are different for how they should work.

`.try_into()`, as a fallible version of `.into()`, mostly transforms the "shape" of the value to fit another type.

`.parse()` can be considered the reverse of `.to_string()`, will read the string content to reconstruct a value in the target type.

Additionally, `TryFrom` must satisfy this relationship, which is not bound for `FromStr`:

- `T: From<S>` ⇒ `T: TryFrom<S, Error=!>`

* * *

As a concrete example:

```rust
use std::convert::TryInto;
use serde_json::{Value, json}; 

fn main() {
    let a: Value = "[1, 2, 3]".try_into().unwrap();
    let b: Value = "[1, 2, 3]".parse().unwrap();
    assert_eq!(dbg!(a), json!("[1, 2, 3]"));
    assert_eq!(dbg!(b), json!( [1, 2, 3] ));
}

```

---

<div class="post-metadata">

### Author: ![yaahc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/yaahc/32/6606_2.png) [@yaahc](https://internals.rust-lang.org/u/yaahc)
#### Post date: [May 14, 2020, 3:42pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/7 "2020-05-14T15:42:14Z")

</div>

One problem that I haven't seen mentioned is that TryFrom doesn't get to use deref coercion the same way FromStr can due to the lack of an explicit receiving type. Using TryFrom exclusively would require a lot of additions of as\_ref() or &\* to code that otherwise just works via FromStr.

---

<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: [August 12, 2020, 3:43pm UTC](https://internals.rust-lang.org/t/pre-rfc-deprecate-fromstr-in-favor-of-tryfrom-str/12331/8 "2020-08-12T15:43:48Z")

</div>

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