Lifetime works inside impl but not outside

Hi folks,

Could you please give me a hint, what's wrong here?

pub trait RemovePrefixSuffix {
    fn remove_prefix(&self, separator: &str) -> &str;
    fn remove_suffix(&self, separator: &str) -> &str;
}
impl RemovePrefixSuffix for &str {
    fn remove_prefix(&self, separator: &str) -> &str {
        self.strip_prefix(separator).unwrap_or(self)
    }
    fn remove_suffix(&self, separator: &str) -> &str {
        self.strip_suffix(separator).unwrap_or(self)
    }
}
impl RemovePrefixSuffix for String {
    fn remove_prefix(&self, separator: &str) -> &str {
        self.strip_prefix(separator).unwrap_or(self)
    }
    fn remove_suffix(&self, separator: &str) -> &str {
        self.strip_suffix(separator).unwrap_or(self)
    }
}

pub trait RemoveAndSplit {
    fn lsplit(&self, separator: &str) -> Option<(&str, &str)>;
    fn rsplit(&self, separator: &str) -> Option<(&str, &str)>;
}
impl RemoveAndSplit for &str {
    fn lsplit(&self, separator: &str) -> Option<(&str, &str)> {
        self.remove_prefix(separator).split_once(separator)
    }
    fn rsplit(&self, separator: &str) -> Option<(&str, &str)> {
        self.remove_suffix(separator).rsplit_once(separator)
    }
}
impl RemoveAndSplit for String {
    fn lsplit(&self, separator: &str) -> Option<(&str, &str)> {
        // OK
        self.remove_prefix(separator).split_once(separator)
    }
    fn rsplit(&self, separator: &str) -> Option<(&str, &str)> {
        // OK
        self.remove_suffix(separator).rsplit_once(separator)
    }
}

fn lsplit_outide_trait<'a>(s: &'a str, separator: &str) -> Option<(&'a str, &'a str)> {
    // ERROR: returns a value referencing data owned by the current function
    s.remove_prefix(separator).split_once(separator)
}

Your traits are implemented for &str and take &self, so you need &&str to call the trait methods. In the String implementations, Deref coercion is producing &’short &str from the &’short String.

In your free function, you have to take a local reference to get an &’short &’a str to call the methods, and they can only give you &’short str as output. You can fix
this by implementing the traits for str instead of &str to avoid the double-reference:

-impl RemovePrefixSuffix for &str {
+impl RemovePrefixSuffix for str {
-impl RemoveAndSplit for &str {
+impl RemoveAndSplit for str {
3 Likes

Yes, that fixed that. Thank you!