Kendrick johnson
Kendrick johnson

Reputation: 322

`lifetime arguments are not allowed for this type` in trait with generic result type

pub struct Article<'a> {
    pub id: &'a str,
    pub title: &'a str,
    pub content: &'a str,
    pub description: &'a str,
}
pub struct Diary<'a> {
    pub id: &'a str,
    pub title: &'a str,
    pub content: &'a str,
}

Using trait to abstract the method with the type has lifetime but the error is confusing. How can I handle lifetime parameter in generic result type in trait.

pub trait Publish<'a, T: 'a> {
    fn publish(self) -> Result<T, Error>;
}

impl<'a> Publish<'a> for Article<'a> {
    fn publish(self) -> Result<Article<'a>, Error> {
        let result = Article {
            id: self.id,
            title: self.title,
            content: self.content,
            description: self.description,
        };

        Ok(result.render())
    }

}

impl<'a> Publish<'a> for Diary<'a> {
  fn publish(self) -> Result<Diary<'a>, Error> {
  // almost samle as below
  }
}

Upvotes: 0

Views: 588

Answers (1)

cdhowie
cdhowie

Reputation: 169528

The way you'd express this is with a bound on the generic type T:

pub trait Publish<'a, T: 'a> {
    fn publish(self) -> Result<T, Error>;
}

However, this raises the question of why you need the lifetime here. The answer is that you don't, and you can leave that detail up to the trait implementations, so your trait should be:

pub trait Publish<T> {
    fn publish(self) -> Result<T, Error>;
}

Now you need to fix your implementations. They shouldn't have a generic parameter T in the first place since their types are fully known -- since the return type of the method is Result<Article<'a>, Error> for example, we know that the trait's T is Article<'a>.

This is also the right place to convey the lifetime information, as mentioned above.

So, your implementations would change to:

impl<'a> Publish<Article<'a>> for Article<'a> {
impl<'a> Publish<Diary<'a>> for Diary<'a> {

Upvotes: 1

Related Questions