Why Is TryFrom<&str> Not Auto-Implemented for Implementors of FromStr?

⚓ Rust    📅 2026-06-14    👤 surdeus    👁️ 1      

surdeus

I have a trait and an example struct implementation:

pub trait ResourceId: Debug + Clone + Eq + PartialEq + FromStr {}

pub struct ItemId(String);

impl FromStr for ItemId {
    type Err = ParseIdError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.starts_with("item-") {
            Ok(Self(s.to_string()) 
        } else { 
            Err(...) 
        }
    }
}

impl ResourceId for ItemId {}

I'm using these values with serde, so I'm using TryFrom<&str> in deserialization:

#[derive(Debug, ..., Serialize, Deserialize)]
#[serde(try_from = "&str")]
pub struct ItemId(String);

So I can absolutely do FromStr::<ItemId>::from_str(s) to get an ItemId, but serde compilation fails for the above as TryFrom<&str> is not implemented:

the trait bound `ItemId: TryFrom<&str>` is not satisfied [E0277]
Help: the trait `From<&str>` is not implemented for `ItemId`
Note: required for `&str` to implement `Into<ItemId>`
Note: required for `ItemId` to implement `TryFrom<&str>`

If I manually implement TryFrom<&str> and use FromStr::from_str as the implementation, it all works.

Due to the orphan rules, I can't do this:

impl<T, E> TryFrom<&str> for T where T: FromStr<Err = E> {
    type Error = E;
    
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        FromStr::from_str(value)
    }
}

Do I need to manually create all of these TryFrom implementations for all of my ResourceId types? Why does FromStr which is a fallible conversion from &str, not automatically imply TryFrom<&str>?

2 posts - 2 participants

Read full topic

🏷️ Rust_feed