Skip to content

Commit d89b31a

Browse files
committed
fixup! More generic impl of Replacer for closures
Refactored code to be able to use two different lifetimes `'a` and `'b` for the `&'a Captures<'b>` argument while allowing the return type to depend on either `'a` or `'b`.
1 parent 664a0f2 commit d89b31a

File tree

2 files changed

+13
-29
lines changed

2 files changed

+13
-29
lines changed

src/regex/string.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,18 +2374,18 @@ impl<'c, 'h> core::iter::FusedIterator for SubCaptureMatches<'c, 'h> {}
23742374
/// Contains helper trait for blanket implementation for [`Replacer`].
23752375
mod replacer_closure {
23762376
use super::*;
2377-
/// If a closure implements this for all `'a`, then it also implements
2378-
/// [`Replacer`].
2379-
pub trait ReplacerClosure<'a>
2377+
/// If a closure implements this for all `&'a Captures<'b>`, then it also
2378+
/// implements [`Replacer`].
2379+
pub trait ReplacerClosure<Arg>
23802380
where
2381-
Self: FnMut(&'a Captures<'a>) -> <Self as ReplacerClosure<'a>>::Output,
2381+
Self: FnMut(Arg) -> <Self as ReplacerClosure<Arg>>::Output,
23822382
{
2383-
/// Return type of the closure (may depend on lifetime `'a`).
2383+
/// Return type of the closure (may depend on lifetime `'a` or `'b`).
23842384
type Output: AsRef<str>;
23852385
}
2386-
impl<'a, F: ?Sized, O> ReplacerClosure<'a> for F
2386+
impl<'a, 'b, F, O> ReplacerClosure<&'a Captures<'b>> for F
23872387
where
2388-
F: FnMut(&'a Captures<'a>) -> O,
2388+
F: ?Sized + FnMut(&'a Captures<'b>) -> O,
23892389
O: AsRef<str>,
23902390
{
23912391
type Output = O;
@@ -2428,8 +2428,8 @@ use replacer_closure::*;
24282428
///
24292429
/// # Implementation by closures
24302430
///
2431-
/// Closures that take an argument of type `&'a Captures<'b>` for any `'a` and
2432-
/// `'b: 'a` and which return a type `T: AsRef<str>` (that may depend on `'a`
2431+
/// Closures that take an argument of type `&'a Captures<'b>` (for any `'a`
2432+
/// and `'b`) and which return a type `T: AsRef<str>` (that may depend on `'a`
24332433
/// or `'b`) implement the `Replacer` trait through a [blanket implementation].
24342434
///
24352435
/// [blanket implementation]: Self#impl-Replacer-for-F
@@ -2575,18 +2575,18 @@ impl<'a> Replacer for &'a Cow<'a, str> {
25752575
/// Blanket implementation of `Replacer` for closures.
25762576
///
25772577
/// This implementation is basically the following, except that the return type
2578-
/// `T` may optionally depend on lifetime `'a`.
2578+
/// `T` may optionally depend on the lifetimes `'a` and `'b`.
25792579
///
25802580
/// ```ignore
25812581
/// impl<F, T> Replacer for F
25822582
/// where
2583-
/// F: for<'a> FnMut(&'a Captures<'a>) -> T,
2584-
/// T: AsRef<str>, // `T` may also depend on `'a`, which cannot be expressed easily
2583+
/// F: for<'a, 'b> FnMut(&'a Captures<'b>) -> T,
2584+
/// T: AsRef<str>, // `T` may depend on `'a` or `'b`, which can't be expressed easily
25852585
/// {
25862586
/// /* … */
25872587
/// }
25882588
/// ```
2589-
impl<F: for<'a> ReplacerClosure<'a>> Replacer for F {
2589+
impl<F: for<'a, 'b> ReplacerClosure<&'a Captures<'b>>> Replacer for F {
25902590
fn replace_append(&mut self, caps: &Captures<'_>, dst: &mut String) {
25912591
dst.push_str((*self)(caps).as_ref());
25922592
}

tests/misc.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,4 @@ mod replacer_closure_lifetimes {
170170
);
171171
assert_eq!(s, "x");
172172
}
173-
// Additionally demand that its sufficient if the closure accepts a single
174-
// lifetime `'u` which is used both for the reference to and the lifetime
175-
// argument of the `Captures` argument. Note that `Captures<'u>` is
176-
// covariant over `'u`.
177-
#[test]
178-
fn unified_lifetime() {
179-
fn coerce<F: for<'u> FnMut(&'u Captures<'u>) -> Cow<'u, str>>(
180-
f: F,
181-
) -> F {
182-
f
183-
}
184-
let s = Regex::new("x")
185-
.unwrap()
186-
.replace_all("x", coerce(|caps| Cow::Borrowed(&caps[0])));
187-
assert_eq!(s, "x");
188-
}
189173
}

0 commit comments

Comments
 (0)