Overflow evaluating the requirement in compiler


#1

I want to implement some parametric wrapper type, which implements FromStr for its inner type, while supporting parse error wrapping at the same time in generic way.

So I implement FromError<T> for my type’s parse error type. Now I need to set type bounds to for my type parameter T and for its parse error type <T as FromStr>::Err so that:

  • T must implement FromStr, to parse it before wrapping into my type,
  • my type’s error type must have FromError<<T as FromStr>::Err> implementation in order to wrap parse error.

Here is minimal code to illustrate my idea:

use std::error::FromError;
use std::str::FromStr;
use std::num::ParseIntError;

#[derive(Debug)]
struct Value<T>(T);

#[derive(Debug)]
struct ValueParseError;

impl FromError<ParseIntError> for ValueParseError {
    fn from_error(e: ParseIntError) -> ValueParseError {
        ValueParseError
    }
}

impl<T> FromStr for Value<T>
where T: FromStr, <Self as FromStr>::Err: FromError<<T as FromStr>::Err>
{
    type Err = ValueParseError;
    fn from_str(s: &str) -> Result<Value<T>, ValueParseError> {
        s.parse::<T>().map_err(FromError::from_error).map(Value)
    }
}

fn main() {
    let v = "123".parse::<Value<usize>>();
    println!("{:?}", v);
}

This code gives the following compilation error:

test.rs:1:1: 1:1 error: overflow evaluating the requirement `<_ as core::str::FromStr>::Err` [E0275]
test.rs:1 use std::error::FromError;
          ^
test.rs:1:1: 1:1 note: consider adding a `#![recursion_limit="128"]` attribute to your crate
test.rs:1 use std::error::FromError;

When I add #![recursion_limit="1024"] into my test, I get the following error:

thread 'rustc' has overflowed its stack
zsh: illegal hardware instruction (core dumped)  rustc test.rs

Which is not very unusual :smile:

My question is, how can I explain these bounds to compiler so it understands me and doesn’t die in infinite recursion?

Thank you.


#2

I resolved the issue by replacing <Self as FromStr>::Err with concrete type:

where T: FromStr, ValueParseError: FromError<<T as FromStr>::Err>

But still I’m not quite sure if my original example should lead to such an ICE.


#3

What is ValueParseError? A struct or a trait?