Closed
Description
EDITED: MCVE is here: #67684 (comment)
I received this compiler bug:
sand:mesa_x dpp$ cargo test
Compiling mesa_x v0.1.0 (/Users/dpp/proj/mesa_x)
error: internal compiler error: src/librustc_traits/normalize_erasing_regions.rs:42: could not fully normalize `fn() -> <impl combine::Parser as combine::Parser>::PartialState {<<impl combine::Parser as combine::Parser>::PartialState as std::default::Default>::default}`
thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:931:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
note: the compiler unexpectedly panicked. this is a bug.
Compiling with this cargo.toml file:
[package]
name = "mesa_x"
version = "0.1.0"
authors = ["David Pollak <feeder.of.the.bears@gmail.com>"]
edition = "2018"
[dependencies]
# nom = "5.0.1"
combine = "3.8.1"
And this main.rs
:
#[macro_use]
extern crate combine;
use combine::parser::char::{alpha_num, char, digit, letter, spaces};
use combine::stream::{Stream};
use combine::{
between, choice, attempt, easy,
many, many1, none_of, optional, parser, sep_by, Parser,
};
#[derive(Debug, PartialEq)]
pub struct Address {}
#[derive(Debug, PartialEq)]
pub enum Range {}
#[derive(Debug, PartialEq)]
pub enum Function {}
#[derive(Debug, PartialEq)]
pub enum Expression {
Int(i128),
Float(f64),
Str(String),
Identifier(String),
Address(Address),
Range(Range),
Function(String, Vec<Expression>),
Infix(Function, Box<Expression>, Box<Expression>),
Expression(Box<Expression>),
}
// `impl Parser` can be used to create reusable parsers with zero overhead
fn expr_<I>() -> impl Parser<Input = I, Output = Expression>
where
I: Stream<Item = char, Error = easy::ParseError<I>>,
// Necessary due to rust-lang/rust#24159
// I::Error: ParseError<I::Item, I::Range, I::Position>,
{
let int2 = between(optional(spaces()), optional(spaces()), (optional(char('-')), many1(digit())))
.and_then(|(sign, s): (Option<char>, String)| {
match (sign, s.parse::<i128>()) {
(Some('-'), Ok(r)) => Ok(Expression::Int(r * -1i128)),
(_, Ok(r)) => Ok(Expression::Int(r)),
(_, Err(_x)) => Err(easy::Error::Expected(easy::Info::Borrowed("combine"))),
}
});
let string = between(
(optional(spaces()), char('"')),
(char('"'), optional(spaces())),
many(none_of("\"".chars())),
)
.map(|s| Expression::Str(s));
let identifier = (spaces(), letter(), many(alpha_num()))
.map(|(_, c, st): ((), char, String)| c.to_string() + &st);
let identifier2 = (spaces(), letter(), many(alpha_num()), spaces())
.map(|(_, c, st, _): ((), char, String, ())| Expression::Identifier(c.to_string() + &st));
let comma_list = sep_by(expr(), (optional(spaces()), char(','), optional(spaces()))).map(|v: Vec<Expression>| v);
let function = (
identifier,
between(char('('),
char(')'), comma_list)
)
.map(|(id, exprs)| Expression::Function(id, exprs));
choice((attempt(function), attempt(identifier2), attempt(string), attempt(int2))) //.skip_spaces()
}
parser! {
fn expr[I]()(I) -> Expression
where [I: Stream<Item = char, Error = easy::ParseError<I>>]
{
expr_()
}
}
#[test]
fn test_parsing() {
let test_exprs = vec![
r#"147"#,
r#""Hello World""#,
r#"true"#,
r#"if(32, "yes", "no")"#,
r#"if(true, "yes", "no")"#,
r#" "Hello World""#,
r#"-32"#,
r#"32.99"#,
r#"-32.822"#,
//r#"SuM(a1:$B7)"#,
//r#"3 + 39"#,
//r#"IF(a1, SUM(a1:$b$7), 3 + 39)"#,
];
for item in test_exprs {
match expr().easy_parse(item) {
Ok((_x, "")) => {
//println!("Got {:#?}", x);
assert!(true)},
Ok((_, x)) => assert!(
false,
format!("Failed to parse whole thing... remaining '{}'", x)
),
Err(x) => assert!(false, format!("Trying '{}', got Error {:#?}", item, x)),
}
}
}
fn main() {
println!("Hello, world!");
}