[Solved] Changing 'use' statements cause error:

#1
  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?

0 Likes

[solved] Core::str vs std::str
#2

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?

0 Likes

#3

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

#4
  1. You’re correct. Thanks!

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

1 Like