Skip to content

Commit 224467c

Browse files
committed
Revert GAT parser trait and use generic lifetime on the trait
The GAT version of the parser trait was slightly cleaner but prevented map closures from reborrowing the input, as `<F: for<'i> Fn(P::Output<'i>) -> O, O>` forces a single concrete type for `O`. See also e9525f8
1 parent c844659 commit 224467c

File tree

8 files changed

+198
-174
lines changed

8 files changed

+198
-174
lines changed

crates/utils/src/parser/base.rs

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,15 @@ pub type ParseResult<'i, T> = Result<(T, &'i [u8]), (ParseError, &'i [u8])>;
1414
/// Parser trait.
1515
///
1616
/// Implementations should avoid allocating where possible.
17-
pub trait Parser: Sized {
17+
pub trait Parser<'i>: Sized {
1818
/// Type of the value produced by [`parse`](Self::parse) when successful.
19-
///
20-
/// Generic over the input `'i` lifetime.
21-
type Output<'i>;
19+
type Output;
2220

2321
/// Type of the chained parser returned by [`then`](Self::then).
2422
///
2523
/// This is used to allow multiple [`then`](Self::then) calls to extend one tuple, instead of
2624
/// nesting tuples inside each other.
27-
type Then<T: Parser>: Then<Self, T>;
25+
type Then<T: Parser<'i>>: Then<'i, Self, T>;
2826

2927
/// Parse the given sequence of bytes.
3028
///
@@ -40,7 +38,7 @@ pub trait Parser: Sized {
4038
/// assert_eq!(parser::u32().parse(b"1234abc"), Ok((1234, &b"abc"[..])));
4139
/// assert!(parser::u32().parse(b"abc1234").is_err());
4240
/// ```
43-
fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>>;
41+
fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output>;
4442

4543
// Provided methods
4644

@@ -56,7 +54,7 @@ pub trait Parser: Sized {
5654
/// Ok(((123, -123), &b""[..]))
5755
/// );
5856
/// ```
59-
fn then<T: Parser>(self, next: T) -> Self::Then<T> {
57+
fn then<T: Parser<'i>>(self, next: T) -> Self::Then<T> {
6058
Then::then(self, next)
6159
}
6260

@@ -83,7 +81,7 @@ pub trait Parser: Sized {
8381
/// Ok((1000, &b""[..]))
8482
/// );
8583
/// ```
86-
fn or<T: for<'i> Parser<Output<'i> = Self::Output<'i>>>(self, alternative: T) -> Or<Self, T> {
84+
fn or<T: Parser<'i, Output = Self::Output>>(self, alternative: T) -> Or<Self, T> {
8785
Or {
8886
first: self,
8987
second: alternative,
@@ -102,7 +100,19 @@ pub trait Parser: Sized {
102100
/// Ok((246, &b""[..]))
103101
/// );
104102
/// ```
105-
fn map<O, F: for<'i> Fn(Self::Output<'i>) -> O>(self, f: F) -> Map<Self, F> {
103+
///
104+
/// Closure that returns a value borrowing from both its input and an outer variable:
105+
/// ```
106+
/// # use utils::parser::{self, Parser};
107+
/// let my_vec = vec![1, 2, 3];
108+
/// assert_eq!(
109+
/// parser::take_while(u8::is_ascii_digit)
110+
/// .map(|x| (x, my_vec.as_slice()))
111+
/// .parse(b"123"),
112+
/// Ok(((&b"123"[..], &[1, 2, 3][..]), &b""[..]))
113+
/// );
114+
/// ```
115+
fn map<O, F: Fn(Self::Output) -> O>(self, f: F) -> Map<Self, F> {
106116
Map {
107117
parser: self,
108118
map_fn: f,
@@ -127,7 +137,25 @@ pub trait Parser: Sized {
127137
/// Err((ParseError::Custom("input too large"), &b"200"[..]))
128138
/// );
129139
/// ```
130-
fn map_res<O, F: for<'i> Fn(Self::Output<'i>) -> Result<O, &'static str>>(
140+
///
141+
/// Closure that returns a value borrowing from both its input and an outer variable:
142+
/// ```
143+
/// # use utils::parser::{self, Parser};
144+
/// let my_vec = vec![1, 2, 3];
145+
/// assert_eq!(
146+
/// parser::take_while(u8::is_ascii_digit)
147+
/// .map_res(|x| {
148+
/// if x.len() < 100 {
149+
/// Ok((x, my_vec.as_slice()))
150+
/// } else {
151+
/// Err("expected more digits")
152+
/// }
153+
/// })
154+
/// .parse(b"123"),
155+
/// Ok(((&b"123"[..], &[1, 2, 3][..]), &b""[..]))
156+
/// );
157+
/// ```
158+
fn map_res<O, F: Fn(Self::Output) -> Result<O, &'static str>>(
131159
self,
132160
f: F,
133161
) -> MapResult<Self, F> {
@@ -172,9 +200,9 @@ pub trait Parser: Sized {
172200
/// Ok(([12, 34, 56], &b""[..]))
173201
/// );
174202
/// ```
175-
fn repeat_n<const N: usize, S: Parser>(self, separator: S) -> RepeatN<N, Self, S>
203+
fn repeat_n<const N: usize, S: Parser<'i>>(self, separator: S) -> RepeatN<N, Self, S>
176204
where
177-
for<'i> Self::Output<'i>: Copy + Default,
205+
Self::Output: Copy + Default,
178206
{
179207
RepeatN {
180208
parser: self,
@@ -197,13 +225,13 @@ pub trait Parser: Sized {
197225
/// assert_eq!(parser.parse(b"12,34,56,78"), Ok((vec![12, 34, 56, 78], &b""[..])));
198226
/// assert!(parser.parse(b"12,34").is_err());
199227
/// ```
200-
fn repeat_arrayvec<const N: usize, S: Parser>(
228+
fn repeat_arrayvec<const N: usize, S: Parser<'i>>(
201229
self,
202230
separator: S,
203231
min_elements: usize,
204232
) -> RepeatArrayVec<N, Self, S>
205233
where
206-
for<'a> Self::Output<'a>: Copy + Default,
234+
Self::Output: Copy + Default,
207235
{
208236
RepeatArrayVec {
209237
parser: self,
@@ -226,7 +254,7 @@ pub trait Parser: Sized {
226254
/// assert_eq!(parser.parse(b"12,34,56,78"), Ok((vec![12, 34, 56, 78], &b""[..])));
227255
/// assert!(parser.parse(b"12,34").is_err());
228256
/// ```
229-
fn repeat<S: Parser>(self, separator: S, min_elements: usize) -> RepeatVec<Self, S> {
257+
fn repeat<S: Parser<'i>>(self, separator: S, min_elements: usize) -> RepeatVec<Self, S> {
230258
RepeatVec {
231259
parser: self,
232260
separator,
@@ -265,7 +293,7 @@ pub trait Parser: Sized {
265293
/// Ok((123, &b""[..]))
266294
/// );
267295
/// ```
268-
fn with_prefix<T: Parser>(self, prefix: T) -> WithPrefix<Self, T> {
296+
fn with_prefix<T: Parser<'i>>(self, prefix: T) -> WithPrefix<Self, T> {
269297
WithPrefix {
270298
parser: self,
271299
prefix,
@@ -286,7 +314,7 @@ pub trait Parser: Sized {
286314
/// Ok((123, &b""[..]))
287315
/// );
288316
/// ```
289-
fn with_suffix<T: Parser>(self, suffix: T) -> WithSuffix<Self, T> {
317+
fn with_suffix<T: Parser<'i>>(self, suffix: T) -> WithSuffix<Self, T> {
290318
WithSuffix {
291319
parser: self,
292320
suffix,
@@ -324,7 +352,7 @@ pub trait Parser: Sized {
324352
/// assert_eq!(parser::u32().parse_complete("1234").unwrap(), 1234);
325353
/// assert!(parser::u32().parse_complete("1234abc").is_err());
326354
/// ```
327-
fn parse_complete<'i>(&self, input: &'i str) -> Result<Self::Output<'i>, InputError> {
355+
fn parse_complete(&self, input: &'i str) -> Result<Self::Output, InputError> {
328356
match self.parse(input.as_bytes()).map_with_input(input)? {
329357
(v, []) => Ok(v),
330358
(_, remaining) => Err(InputError::new(input, remaining, "expected end of input")),
@@ -351,7 +379,7 @@ pub trait Parser: Sized {
351379
/// ]
352380
/// );
353381
/// ```
354-
fn parse_all<'i>(&self, input: &'i str) -> Result<Vec<Self::Output<'i>>, InputError> {
382+
fn parse_all(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError> {
355383
ParserRef(self)
356384
.repeat(Constant(()), 0)
357385
.parse_complete(input)
@@ -376,7 +404,7 @@ pub trait Parser: Sized {
376404
/// ]
377405
/// );
378406
/// ```
379-
fn parse_lines<'i>(&self, input: &'i str) -> Result<Vec<Self::Output<'i>>, InputError> {
407+
fn parse_lines(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError> {
380408
ParserRef(self)
381409
.with_suffix(Eol())
382410
.repeat(Constant(()), 0)
@@ -459,25 +487,25 @@ pub trait Parser: Sized {
459487

460488
// Workaround to allow using methods which consume a parser in methods which take references.
461489
struct ParserRef<'a, P>(&'a P);
462-
impl<P: Parser> Parser for ParserRef<'_, P> {
463-
type Output<'i> = P::Output<'i>;
464-
type Then<T: Parser> = Unimplemented;
490+
impl<'i, P: Parser<'i>> Parser<'i> for ParserRef<'_, P> {
491+
type Output = P::Output;
492+
type Then<T: Parser<'i>> = Unimplemented;
465493

466494
#[inline]
467-
fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
495+
fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
468496
self.0.parse(input)
469497
}
470498
}
471499

472500
/// Matches the string literal exactly.
473501
///
474502
/// Normally used with [`with_prefix`](Parser::with_prefix)/[`with_suffix`](Parser::with_suffix).
475-
impl Parser for &'static str {
476-
type Output<'i> = ();
477-
type Then<T: Parser> = Then2<Self, T>;
503+
impl<'i> Parser<'i> for &'static str {
504+
type Output = ();
505+
type Then<T: Parser<'i>> = Then2<Self, T>;
478506

479507
#[inline]
480-
fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
508+
fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
481509
// This is faster than using strip_prefix for the common case where the string is a short
482510
// string literal known at compile time.
483511
if input.len() >= self.len() && self.bytes().zip(input).all(|(a, &b)| a == b) {
@@ -491,12 +519,12 @@ impl Parser for &'static str {
491519
/// Matches the byte exactly.
492520
///
493521
/// Normally used with [`with_prefix`](Parser::with_prefix)/[`with_suffix`](Parser::with_suffix).
494-
impl Parser for u8 {
495-
type Output<'i> = ();
496-
type Then<T: Parser> = Then2<Self, T>;
522+
impl<'i> Parser<'i> for u8 {
523+
type Output = ();
524+
type Then<T: Parser<'i>> = Then2<Self, T>;
497525

498526
#[inline]
499-
fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
527+
fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
500528
if input.first() == Some(self) {
501529
Ok(((), &input[1..]))
502530
} else {
@@ -506,18 +534,18 @@ impl Parser for u8 {
506534
}
507535

508536
/// Allow custom functions and closures to be used as parsers.
509-
impl<O, F: Fn(&[u8]) -> ParseResult<O>> Parser for F {
510-
type Output<'i> = O;
511-
type Then<T: Parser> = Then2<Self, T>;
537+
impl<'i, O, F: Fn(&'i [u8]) -> ParseResult<'i, O>> Parser<'i> for F {
538+
type Output = O;
539+
type Then<T: Parser<'i>> = Then2<Self, T>;
512540

513541
#[inline]
514-
fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
542+
fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
515543
self(input)
516544
}
517545
}
518546

519547
/// Trait for types that have a canonical parser.
520548
pub trait Parseable {
521-
type Parser: for<'i> Parser<Output<'i> = Self>;
549+
type Parser: for<'i> Parser<'i, Output = Self>;
522550
const PARSER: Self::Parser;
523551
}

0 commit comments

Comments
 (0)