[Solved] Changing 'use' statements cause error:

  1. The following code compiles:
use super::*;


/*

use combine::{satisfy, Parser, many1};
use combine::char::{alpha_num, letter, string, digit};
use combine_language::{Identifier, LanguageEnv, LanguageDef};
use combine::parser::combinator::recognize;
use combine::skip_many1;
use combine::optional;
use combine::parser::item::item;
use combine::skip_many;
use combine::error::UnexpectedParse;
use combine::combinator::StrLike;

*/



use combine::error::UnexpectedParse;
use combine::parser::byte::digit;
use combine::parser::choice::optional;
use combine::parser::item::item;
use combine::parser::range::recognize;
use combine::parser::repeat::{skip_many, skip_many1};
use combine::Parser;



use core::str;


fn main() {
    let mut parser = recognize((
        skip_many1(digit()),
        optional((item(b'.'), skip_many(digit())))))
        .and_then(|bs: &[u8]| {
            // `bs` only contains digits which are ascii and thus UTF-8
            let s = unsafe { core::str::from_utf8_unchecked(bs) };
            s.parse::<f64>().map_err(|_| UnexpectedParse::Unexpected)
        });
    let result = parser.parse(&b"123.45"[..]);
    assert_eq!(result, Ok((123.45, &b""[..])));
}



#[test]
fn test_00() {
    // main();
}
  1. Now, suppose the use statements:
use super::*;



use combine::{satisfy, Parser, many1};
use combine::char::{alpha_num, letter, string, digit};
use combine_language::{Identifier, LanguageEnv, LanguageDef};
use combine::parser::combinator::recognize;
use combine::skip_many1;
use combine::optional;
use combine::parser::item::item;
use combine::skip_many;
use combine::error::UnexpectedParse;
use combine::combinator::StrLike;




/*
use combine::error::UnexpectedParse;
use combine::parser::byte::digit;
use combine::parser::choice::optional;
use combine::parser::item::item;
use combine::parser::range::recognize;
use combine::parser::repeat::{skip_many, skip_many1};
use combine::Parser;
*/



use core::str;


fn main() {
    let mut parser = recognize((
        skip_many1(digit()),
        optional((item(b'.'), skip_many(digit())))))
        .and_then(|bs: &[u8]| {
            // `bs` only contains digits which are ascii and thus UTF-8
            let s = unsafe { core::str::from_utf8_unchecked(bs) };
            s.parse::<f64>().map_err(|_| UnexpectedParse::Unexpected)
        });
    let result = parser.parse(&b"123.45"[..]);
    assert_eq!(result, Ok((123.45, &b""[..])));
}



#[test]
fn test_00() {
    // main();
}

  1. This resultsin compile errors of:
   |
38 |         .and_then(|bs: &[u8]| {
   |          ^^^^^^^^ the trait `std::iter::Extend<_>` is not implemented for `&[u8]`
   |
   = note: required because of the requirements on the impl of `combine::Parser` for `combine::combinator::Recognize<&[u8], (combine::combinator::SkipMany1<combine::char::Digit<_>>, combine::combinator::Optional<(combine::combinator::Token<_>, combine::combinator::SkipMany<combine::char::Digit<_>>)>)>`


   |
35 |     let mut parser = recognize((
   |                      ^^^^^^^^^ the trait `std::iter::Extend<_>` is not implemented for `&[u8]`
   |
   = note: required by `combine::combinator::recognize`


   |
43 |     let result = parser.parse(&b"123.45"[..]);
   |                         ^^^^^
   |
   = note: the method `parse` exists but the following trait bounds were not satisfied:
           `combine::combinator::AndThen<combine::combinator::Recognize<&[u8], (combine::combinator::SkipMany1<combine::char::Digit<_>>, combine::combinator::Optional<(combine::combinator::Token<_>, combine::combinator::SkipMany<combine::char::Digit<_>>)>)>, [closure@20_vm/35_vm_math/src/mma/parser/blah.rs:38:19: 42:10]> : combine::Parser`

What's going on, and how do we fix this?

Using:


use combine::error::UnexpectedParse;
use combine::parser::byte::digit;
use combine::parser::choice::optional;
use combine::parser::item::item;
use combine::parser::range::recognize;
use combine::parser::repeat::{skip_many, skip_many1};
use combine::Parser;


use combine::{satisfy, many1};
use combine::char::{alpha_num, letter, string};
use combine_language::{Identifier, LanguageEnv, LanguageDef};
use combine::combinator::StrLike;

it also compiles (this contains same imported names as the 'broken' one), so the issue seems to be ORDER SENSISTIVE?

There are two different functions named recognize. Your code is expecting to call combine::parser::range::recognize, and fails if you import combine::parser::combinator::recognize instead.

1 Like
  1. You're correct. Thanks!

  2. Turns out I was also swapping combine::byte::digit for combine::char::digit.

1 Like