Skip to content

Commit

Permalink
Use correct lifetimes for SubCaptures and SubCapturesNamed types.
Browse files Browse the repository at this point in the history
This corrects a gaffe of mine. In particular, both types contain
references to a `Captures` *and* the text that was searched, but
only names one lifetime. In practice, this means that the shortest
lifetime is used, which can be problematic for when one is trying to
extract submatch text.

This also fixes the lifetime annotation on `iter_pos`, which should be
tied to the Captures and not the text.

It was always possible to work around this by using indices.

Fixes #168
  • Loading branch information
BurntSushi committed Aug 5, 2016
1 parent d468016 commit 47bd416
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/re_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,21 +749,21 @@ impl<'t> Captures<'t> {

/// Creates an iterator of all the capture groups in order of appearance
/// in the regular expression.
pub fn iter<'a>(&'a self) -> SubCaptures<'a, 't> {
pub fn iter<'c>(&'c self) -> SubCaptures<'c, 't> {
SubCaptures { idx: 0, caps: self }
}

/// Creates an iterator of all the capture group positions in order of
/// appearance in the regular expression. Positions are byte indices
/// in terms of the original string matched.
pub fn iter_pos(&'t self) -> SubCapturesPos<'t> {
pub fn iter_pos<'c>(&'c self) -> SubCapturesPos<'c> {
SubCapturesPos { idx: 0, slots: &self.slots }
}

/// Creates an iterator of all named groups as an tuple with the group
/// name and the value. The iterator returns these values in arbitrary
/// order.
pub fn iter_named<'a>(&'a self) -> SubCapturesNamed<'a, 't> {
pub fn iter_named<'c>(&'c self) -> SubCapturesNamed<'c, 't> {
SubCapturesNamed {
caps: self,
names: self.named_groups.iter()
Expand Down
26 changes: 13 additions & 13 deletions src/re_unicode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -886,21 +886,21 @@ impl<'t> Captures<'t> {

/// Creates an iterator of all the capture groups in order of appearance
/// in the regular expression.
pub fn iter(&'t self) -> SubCaptures<'t> {
pub fn iter<'c>(&'c self) -> SubCaptures<'c, 't> {
SubCaptures { idx: 0, caps: self, }
}

/// Creates an iterator of all the capture group positions in order of
/// appearance in the regular expression. Positions are byte indices
/// in terms of the original string matched.
pub fn iter_pos(&'t self) -> SubCapturesPos<'t> {
pub fn iter_pos<'c>(&'c self) -> SubCapturesPos<'c> {
SubCapturesPos { idx: 0, slots: &self.slots }
}

/// Creates an iterator of all named groups as an tuple with the group
/// name and the value. The iterator returns these values in arbitrary
/// order.
pub fn iter_named(&'t self) -> SubCapturesNamed<'t> {
pub fn iter_named<'c>(&'c self) -> SubCapturesNamed<'c, 't> {
SubCapturesNamed {
caps: self,
names: self.named_groups.iter()
Expand Down Expand Up @@ -1007,15 +1007,15 @@ impl<'t, 'i> Index<&'i str> for Captures<'t> {
/// expression.
///
/// `'c` is the lifetime of the captures.
pub struct SubCaptures<'c> {
pub struct SubCaptures<'c, 't: 'c> {
idx: usize,
caps: &'c Captures<'c>,
caps: &'c Captures<'t>,
}

impl<'c> Iterator for SubCaptures<'c> {
type Item = Option<&'c str>;
impl<'c, 't> Iterator for SubCaptures<'c, 't> {
type Item = Option<&'t str>;

fn next(&mut self) -> Option<Option<&'c str>> {
fn next(&mut self) -> Option<Option<&'t str>> {
if self.idx < self.caps.len() {
self.idx += 1;
Some(self.caps.at(self.idx - 1))
Expand Down Expand Up @@ -1057,15 +1057,15 @@ impl<'c> Iterator for SubCapturesPos<'c> {
/// name and the value.
///
/// `'c` is the lifetime of the captures.
pub struct SubCapturesNamed<'c> {
caps: &'c Captures<'c>,
pub struct SubCapturesNamed<'c, 't: 'c> {
caps: &'c Captures<'t>,
names: NamedGroupsIter<'c>,
}

impl<'c> Iterator for SubCapturesNamed<'c> {
type Item = (&'c str, Option<&'c str>);
impl<'c, 't> Iterator for SubCapturesNamed<'c, 't> {
type Item = (&'c str, Option<&'t str>);

fn next(&mut self) -> Option<(&'c str, Option<&'c str>)> {
fn next(&mut self) -> Option<(&'c str, Option<&'t str>)> {
self.names.next().map(|(name, pos)| (name, self.caps.at(pos)))
}
}
Expand Down

0 comments on commit 47bd416

Please sign in to comment.