Skip to content

add second "capture" lifetime to SubCaptures and SubCapturesNamed #168

Closed
@defuz

Description

@defuz

I think this code should work:

#[test]
fn test_iter_lifetimes() {
    fn get_first_subcapture<'t>(regex: &Regex, text: &'t str) -> Option<&'t str> {
        let captures = regex.captures(text).unwrap();
        captures.iter().next().unwrap()
    }

    let regex = Regex::new("(a+)(b+)").unwrap();
    let subcapture = get_first_subcapture(&regex, "aabbab");

    assert_eq!(subcapture, Some("aabb"));
}

But today it does not compile:

src/re.rs:956:9: 956:17 error: `captures` does not live long enough
src/re.rs:956         captures.iter().next().unwrap()
                      ^~~~~~~~
src/re.rs:954:82: 957:6 note: reference must be valid for the lifetime 't as defined on the block at 954:81...
src/re.rs:954     fn get_first_subcapture<'t>(regex: &Regex, text: &'t str) -> Option<&'t str> {
src/re.rs:955         let captures = regex.captures(text).unwrap();
src/re.rs:956         captures.iter().next().unwrap()
src/re.rs:957     }
src/re.rs:955:54: 957:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 955:53
src/re.rs:955         let captures = regex.captures(text).unwrap();
src/re.rs:956         captures.iter().next().unwrap()
src/re.rs:957     }

The problem is that subcaptures can not outlive Captures struct, which is wrong. To fix this, we need to add new lifetime:

pub fn iter<'c>(&'c self) -> SubCaptures<'c, 't>

And:

pub struct SubCaptures<'c, 't: 'c> {
    idx: usize,
    caps: &'c Captures<'t>,
}

There is a similar problem with iter_named and SubCapturesNamed. Possibly related to #158

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions