(solved) Lost trying to use winnow

Hello,

I'm trying to use winnow instead of manual parsing stuff... And gosh ! What a headache !

Ok so...

here is my initial naive code :


fn parse_range(input: &mut str) -> winnow::Result<Range> {
    let (start, end) = separated_pair(
        digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
        literal("-"),
        digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
    )
    .parse_next(input)?;

    todo!()
}
bulid output

Compiling aoc_2025_02 v0.1.0 (/home/alban/dev/perso/challenges/rust/aoc/2025/02)
error[E0277]: the trait bound &mut str: Stream is not satisfied
--> aoc/2025/02/src/part1.rs:16:9
|
13 | let (start, end) = separated_pair(
| -------------- required by a bound introduced by this call
...
16 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait Stream is not implemented for &mut str
|
= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str
= note: required for fn(&mut &mut str) -> Result<..., _> {digit1::<..., _>} to implement Parser<&mut str, &str, _>
= note: 1 redundant requirement hidden
= note: required for TryMap<fn(...) -> ... {digit1::<..., _>}, ..., ..., ..., u16, _, ...> to implement Parser<&mut str, u16, _>
note: required by a bound in separated_pair
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/combinator/sequence.rs:116:9
|
106 | pub fn separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>(
| -------------- required by a bound in this function
...
116 | P2: Parser<Input, O2, Error>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in separated_pair
= note: the full name for the type has been written to '/home/alban/dev/perso/challenges/rust/target/debug/deps/aoc_2025_02-ffa5e6080af77e96.long-type-1702773563600961607.txt'
= note: consider using --verbose to print the full type name to the console

error[E0277]: the trait bound &mut str: StreamIsPartial is not satisfied
--> aoc/2025/02/src/part1.rs:14:9
|
14 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^ the trait StreamIsPartial is not implemented for &mut str
|
note: required by a bound in digit1
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/ascii/mod.rs:569:12
|
567 | pub fn digit1<Input, Error>(input: &mut Input) -> Result<::Slice, Error>
| ------ required by a bound in this function
568 | where
569 | Input: StreamIsPartial + Stream,
| ^^^^^^^^^^^^^^^ required by this bound in digit1
help: consider mutably borrowing here
|
14 | (&mut digit1).try_map(|d: &str| u16::from_str_radix(d, 10)),
| +++++ +

error[E0277]: the trait bound &mut str: Stream is not satisfied
--> aoc/2025/02/src/part1.rs:14:16
|
14 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^ the trait Stream is not implemented for &mut str
|
= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str
= note: required for fn(&mut &mut str) -> Result<..., _> {digit1::<..., _>} to implement Parser<&mut str, &str, _>
= note: the full name for the type has been written to '/home/alban/dev/perso/challenges/rust/target/debug/deps/aoc_2025_02-ffa5e6080af77e96.long-type-9307485317051960437.txt'
= note: consider using --verbose to print the full type name to the console

error[E0277]: the trait bound &mut str: Offset<_> is not satisfied
--> aoc/2025/02/src/part1.rs:14:16
|
14 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^ the trait Offset<_> is not implemented for &mut str
|
= help: the following other types implement trait Offset<Start>:
&str implements Offset<Checkpoint<&str, &str>>
&str implements Offset
note: required by a bound in Stream
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/stream/mod.rs:138:19
|
138 | pub trait Stream: Offset<::Checkpoint> + core::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in Stream

error[E0277]: the trait bound &mut str: StreamIsPartial is not satisfied
--> aoc/2025/02/src/part1.rs:15:9
|
15 | literal("-"),
| ^^^^^^^^^^^^ the trait StreamIsPartial is not implemented for &mut str
|
note: required by a bound in literal
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/token/mod.rs:164:12
|
160 | pub fn literal<Literal, Input, Error>(
| ------- required by a bound in this function
...
164 | Input: StreamIsPartial + Stream + Compare,
| ^^^^^^^^^^^^^^^ required by this bound in literal
help: consider mutably borrowing here
|
15 | &mut literal("-"),
| ++++

error[E0277]: the trait bound &mut str: Compare<&str> is not satisfied
--> aoc/2025/02/src/part1.rs:15:9
|
15 | literal("-"),
| ^^^^^^^^^^^^ the trait Compare<&str> is not implemented for &mut str
|
note: required by a bound in literal
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/token/mod.rs:164:39
|
160 | pub fn literal<Literal, Input, Error>(
| ------- required by a bound in this function
...
164 | Input: StreamIsPartial + Stream + Compare,
| ^^^^^^^^^^^^^^^^ required by this bound in literal
help: consider mutably borrowing here
|
15 | &mut literal("-"),
| ++++

error[E0277]: the trait bound &mut str: Stream is not satisfied
--> aoc/2025/02/src/part1.rs:14:9
|
13 | let (start, end) = separated_pair(
| -------------- required by a bound introduced by this call
14 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait Stream is not implemented for &mut str
|
= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str
= note: required for TryMap<fn(...) -> ... {digit1::<..., _>}, ..., ..., ..., u16, _, ...> to implement Parser<&mut str, u16, _>
note: required by a bound in separated_pair
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/combinator/sequence.rs:114:9
|
106 | pub fn separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>(
| -------------- required by a bound in this function
...
114 | P1: Parser<Input, O1, Error>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in separated_pair
= note: the full name for the type has been written to '/home/alban/dev/perso/challenges/rust/target/debug/deps/aoc_2025_02-ffa5e6080af77e96.long-type-724061218608238928.txt'
= note: consider using --verbose to print the full type name to the console

error[E0277]: the trait bound &mut str: Offset<_> is not satisfied
--> aoc/2025/02/src/part1.rs:13:24
|
13 | let (start, end) = separated_pair(
| ^^^^^^^^^^^^^^ the trait Offset<_> is not implemented for &mut str
|
= help: the following other types implement trait Offset<Start>:
&str implements Offset<Checkpoint<&str, &str>>
&str implements Offset
note: required by a bound in Stream
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/stream/mod.rs:138:19
|
138 | pub trait Stream: Offset<::Checkpoint> + core::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in Stream

error[E0277]: the trait bound &mut str: StreamIsPartial is not satisfied
--> aoc/2025/02/src/part1.rs:16:9
|
16 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^ the trait StreamIsPartial is not implemented for &mut str
|
note: required by a bound in digit1
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/ascii/mod.rs:569:12
|
567 | pub fn digit1<Input, Error>(input: &mut Input) -> Result<::Slice, Error>
| ------ required by a bound in this function
568 | where
569 | Input: StreamIsPartial + Stream,
| ^^^^^^^^^^^^^^^ required by this bound in digit1
help: consider mutably borrowing here
|
16 | (&mut digit1).try_map(|d: &str| u16::from_str_radix(d, 10)),
| +++++ +

error[E0277]: the trait bound &mut str: StreamIsPartial is not satisfied
--> aoc/2025/02/src/part1.rs:13:24
|
13 | let (start, end) = separated_pair(
| ^^^^^^^^^^^^^^ the trait StreamIsPartial is not implemented for &mut str
|
= help: the trait StreamIsPartial is implemented for &str
= note: StreamIsPartial is implemented for &str, but not for &mut str
note: required by a bound in literal
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/token/mod.rs:164:12
|
160 | pub fn literal<Literal, Input, Error>(
| ------- required by a bound in this function
...
164 | Input: StreamIsPartial + Stream + Compare,
| ^^^^^^^^^^^^^^^ required by this bound in literal

error[E0277]: the trait bound &mut str: Compare<&str> is not satisfied
--> aoc/2025/02/src/part1.rs:13:24
|
13 | let (start, end) = separated_pair(
| ^^^^^^^^^^^^^^ the trait Compare<&str> is not implemented for &mut str
|
= help: the following other types implement trait Compare<T>:
&str implements Compare<&str>
&str implements Compare<Caseless<&str>>
&str implements Compare<Caseless<char>>
&str implements Compare<char>
= note: Compare<&str> is implemented for &str, but not for &mut str
note: required by a bound in literal
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/token/mod.rs:164:39
|
160 | pub fn literal<Literal, Input, Error>(
| ------- required by a bound in this function
...
164 | Input: StreamIsPartial + Stream + Compare,
| ^^^^^^^^^^^^^^^^ required by this bound in literal

error[E0277]: the trait bound &mut str: Stream is not satisfied
--> aoc/2025/02/src/part1.rs:16:16
|
16 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^ the trait Stream is not implemented for &mut str
|
= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str
= note: required for fn(&mut &mut str) -> Result<..., _> {digit1::<..., _>} to implement Parser<&mut str, &str, _>
= note: the full name for the type has been written to '/home/alban/dev/perso/challenges/rust/target/debug/deps/aoc_2025_02-ffa5e6080af77e96.long-type-5541738307362319280.txt'
= note: consider using --verbose to print the full type name to the console

error[E0277]: the trait bound &mut str: Offset<_> is not satisfied
--> aoc/2025/02/src/part1.rs:16:16
|
16 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^ the trait Offset<_> is not implemented for &mut str
|
= help: the following other types implement trait Offset<Start>:
&str implements Offset<Checkpoint<&str, &str>>
&str implements Offset
note: required by a bound in Stream
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/stream/mod.rs:138:19
|
138 | pub trait Stream: Offset<::Checkpoint> + core::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in Stream

error[E0277]: the trait bound &mut str: Offset<_> is not satisfied
--> aoc/2025/02/src/part1.rs:13:24
|
13 | let (start, end) = separated_pair(
| ___________________^
14 | | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
15 | | literal("-"),
16 | | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
17 | | )
| |
^ the trait Offset<_> is not implemented for &mut str
|
= help: the following other types implement trait Offset<Start>:
&str implements Offset<Checkpoint<&str, &str>>
&str implements Offset
note: required by a bound in Stream
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/stream/mod.rs:138:19
|
138 | pub trait Stream: Offset<::Checkpoint> + core::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in Stream

error[E0277]: the trait bound &mut str: Offset<_> is not satisfied
--> aoc/2025/02/src/part1.rs:18:6
|
18 | .parse_next(&mut input)?;
| ^^^^^^^^^^ the trait Offset<_> is not implemented for &mut str
|
= help: the following other types implement trait Offset<Start>:
&str implements Offset<Checkpoint<&str, &str>>
&str implements Offset
note: required by a bound in Stream
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/stream/mod.rs:138:19
|
138 | pub trait Stream: Offset<::Checkpoint> + core::fmt::Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in Stream

error[E0277]: the trait bound &mut str: Stream is not satisfied
--> aoc/2025/02/src/part1.rs:13:24
|
13 | let (start, end) = separated_pair(
| ___________________^
14 | | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
15 | | literal("-"),
16 | | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
17 | | )
| |
^ the trait Stream is not implemented for &mut str
|
= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str
= note: required for ContextError to implement ParserError<&mut str>
note: required by a bound in separated_pair
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/combinator/sequence.rs:113:12
|
106 | pub fn separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>(
| -------------- required by a bound in this function
...
113 | Error: ParserError,
| ^^^^^^^^^^^^^^^^^^ required by this bound in separated_pair

error[E0277]: the trait bound &mut str: Stream is not satisfied
--> aoc/2025/02/src/part1.rs:14:16
|
14 | digit1.try_map(|d: &str| u16::from_str_radix(d, 10)),
| ^^^^^^^ the trait Stream is not implemented for &mut str
|
= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str
= note: required for ContextError to implement ParserError<&mut str>
note: required by a bound in try_map
--> /home/alban/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/parser.rs:531:12
|
525 | fn try_map<G, O2, E2>(self, map: G) -> impls::TryMap<Self, G, I, O, O2, E, E2>
| ------- required by a bound in this associated function
...
531 | E: ParserError,
| ^^^^^^^^^^^^^^ required by this bound in Parser::try_map

warning: unused variable: content
--> aoc/2025/02/src/part1.rs:6:19
|
6 | pub(crate) fn run(content: &str) -> Result {
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: _content
|
= note: #[warn(unused_variables)] (part of #[warn(unused)]) on by default

For more information about this error, try rustc --explain E0277.
warning: aoc_2025_02 (bin "aoc_2025_02") generated 1 warning
error: could not compile aoc_2025_02 (bin "aoc_2025_02") due to 17 previous errors; 1 warning emitted

I've tried several things, but It's asking so many straits... I'm a bit lost...

I am not familiar with winnow, but you're passing in an &mut &mut str, which is almost certainly not what it wants. Try &mut &str, by changing the parameter type of your function:

fn parse_range(mut input: &str) -> winnow::Result<Range> {

This is what the compiler is hinting about here:

= help: the trait Stream is implemented for &str
= note: Stream is implemented for &str, but not for &mut str

I've tried several things, but It's asking so many straits... I'm a bit lost...

Any time you have a long list of complex errors like this, read the first error in detail, and ignore the rest of them. It is very likely that the rest are consequences of the first, and may be misleading because the compiler tried to continue but with poor information.

And when I mean "in detail", I mean read all of the text of that first error. Each piece of it is meant to be helpful and give you context for what the compiler understands the situation to be, not just a complaint.

3 Likes

Yes I had a &mut &mut I could remove .parse_next(&mut input) => .parse_next(input), but it doesn't change anything : now the error is Stream is not implemented for str

Ok even if I've read the tuto, I did not notice the signatures : &mut &str is the expected input type. ty