1

[EDIT] I am not looking for a solution to have a from_str() (or a constructor) on my struct but rather I was just curious to see if there was a way to implement some native traits which don't take lifetime parameters.

I can indeed easily do without FromStr but there might be some more complex cases when not implementing a Trait would lead to a much more complex / unstable solution


I am trying to implement the FromStr trait for a structure which uses a lifetime parameter

use std::str::FromStr;

#[derive(Debug)]
struct Test<'s> {
    value: &'s str,
}

impl<'s> Test<'s> {
    fn new(val: &'s str) -> Self {
        Test {
            value: val,
        }
    }
}

impl<'s> FromStr for Test<'s> {
    type Err = ();

    fn from_str(t: &str) -> Result<Test<'s>, Self::Err> {
        Ok(Test {
            value: t,
        })
    }
}

fn main() {
    let t1 = Test::new("test 1");
    let t2 = Test::from_str("test 2");

    println!("Test 1 = {:?}", &t1);
    println!("Test 2 = {:?}", &t2);
}

As such it doesn't compile (rightfully so) and I get the following compilation error:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'s` due to conflicting requirements

So I tried to add lifetime requirements to the from_str() function like that:

fn from_str<'t: 's>(t: &'t str) -> Result<Self, Self::Err> { ... }

But then again I have another compiler error (which I understand perfectly too)

error[E0195]: lifetime parameters or bounds on method `from_str` do not match the trait declaration

I can just not implement the trait and add the method to the structure's implementation but I was wondering whether it existed a way to do thing by implementing the trait?

PS: link to the code in a playground

Boris
  • 991
  • 1
  • 9
  • 15
  • [If `FromStr` were implemented like this](https://play.rust-lang.org/?gist=268dd34b78ed748ccad8704940c51962&version=stable&mode=debug&edition=2015), it would have worked, but as it says in the duplicate answer, because `FromStr` does not tie the output lifetime to the input lifetime, it can't be done. – mcarton Sep 24 '18 at 12:33
  • Not quite, I know how to bypass the FromStr constructor. My question was more relative to how one can do to implement a Trait that's outside of my crate when I need to add lifetime parameters – Boris Sep 24 '18 at 12:33
  • The broader question is too vague, akin to "Can I implement a trait?" The answer is yes sometimes, no other times. If, for example, `Test<'s>` contains a `Cow<'s, str>` instead of a `&'s str`, then suddenly it becomes easy to implement `FromStr`. – trent Sep 24 '18 at 12:54
  • See also [Iterator returning items by reference, lifetime issue](https://stackoverflow.com/questions/24574741/iterator-returning-items-by-reference-lifetime-issue) – trent Sep 24 '18 at 13:02
  • interesting thanks for sharing. Out of curiousity, @trentcl would you mind sharing an example with `Cow<'s, str>` I can't get it to work :( – Boris Sep 24 '18 at 13:16
  • Sorry, I should have clarified. [You have to turn it into a `String`](https://play.rust-lang.org/?gist=135a9d20865aabfb2af71f82226584f0&version=stable&mode=debug&edition=2015). – trent Sep 24 '18 at 13:46

0 Answers0