0

I have the following code:

pub trait Regex: RegexClone {
    fn check(&self) -> Result<u32,(/* errors should detail where it fails*/)>;
    fn next(&self) -> Option<Box<dyn Regex>>;
}

pub trait RegexClone {
    fn regex_clone(&self) -> Box<dyn Regex>;
}
    
pub struct PatternAnyCharacter<'a>{
    string: &'a str
}
    
impl RegexClone for PatternAnyCharacter<'_> {
    fn regex_clone(&self) -> Box<dyn Regex> {
        return Box::new(PatternAnyCharacter {string: self.string})
    }
}

impl Regex for PatternAnyCharacter<'_> {
    fn check(&self) -> Result<u32, ()> {
        if self.string.len() > 0 {
            return Ok(1);
        }
        Err(())
    }

    fn next(&self) ->  Option<Box<dyn Regex>> {
        None
    }
}

The idea is that when i call regex_clone i get a new Box<dyn Regex> with the same &str as member, i supossed that since im only using inmutable references when calling regex_clone it would give me a new struct with the same string slice, since is a reference im not moving anything, however the compiler complains the following:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/lib.rs:63:25
   |
63 |         return Box::new(PatternAnyCharacter {string: self.string})
   |                         ^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'_` as defined here...
  --> src/lib.rs:61:41
   |
61 | impl RegexClone for PatternAnyCharacter<'_> {
   |                                         ^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:63:54
   |
63 |         return Box::new(PatternAnyCharacter {string: self.string})
   |                                                      ^^^^^^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
  --> src/lib.rs:63:16
   |
63 |         return Box::new(PatternAnyCharacter {string: self.string})
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `Box<(dyn Regex + 'static)>`
              found `Box<dyn Regex>`

How can i solve this so i can share the same string slice with multiple struct? i thought about foregoing the string slice as member entirely and passing it as parameter to check, but hopefully i can avoid it.

Caesar
  • 6,733
  • 4
  • 38
  • 44
  • 1
    There is something missing from the code, it gives a different error. ``the trait `Regex` is not implemented for `PatternAnyCharacter<'_>` `` at this line: `return Box::new(PatternAnyCharacter {string: self.string})` – aedm Mar 17 '22 at 19:25
  • 2
    `Box` is short for `Box`, which means it can only hold owned vaules, not something borrowed from the environment. – user4815162342 Mar 17 '22 at 19:26
  • @aedm yes, i forgot to include the impl block for regex, gonna do it real quick – Dariem Fabián Hidalgo Arias Mar 17 '22 at 19:59

1 Answers1

0

You need to define at the trait that the returned dyn Regex can't outlive &self if you want to allow it to borrow from parts of &self.:

pub trait RegexClone {
    fn regex_clone<'a>(&'a self) -> Box<dyn Regex + 'a>;
} 

(You can also use an anonymous lifetime (Box<dyn Regex + '_>), but this is easier to understand.)

Side note: I don't think "clone" is the right name for such a function.

Caesar
  • 6,733
  • 4
  • 38
  • 44