Rust: error[E0275]: "overflow evaluating the requirement" triggered by importing a path of length 2

Created on 23 Jan 2019  ·  14Comments  ·  Source: rust-lang/rust

This might be a duplicate of #39959. I'm posting a new issue here as the mechanism that the error is triggered significantly differs from that in the aforementioned issue.

Sample code

[package]
name = "example"
version = "0.1.0"
authors = ["Author"]
edition = "2018"

[dependencies]
tokio = "=0.1.14"
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;

// Comment this out... and everything will work fine
use thisdoesntexistyolo::haha;

struct Something<T: Read + Write> {
    thing: T,
}

impl<'a, T: 'a + Read + Write> Something<T>
where
    &'a T: Read,
{
    fn new(thing: T) -> Something<T> {
        Something { thing }
    }
}

fn main() {
    let file = File::open(Path::new("doesntmatter.txt")).unwrap();
    let mut st: Something<File> = Something::new(file);
}

(Playground)

error[E0432]: unresolved import `thisdoesntexistyolo`
 --> src/main.rs:6:5
  |
6 | use thisdoesntexistyolo::haha;
  |     ^^^^^^^^^^^^^^^^^^^ use of undeclared type or module `thisdoesntexistyolo`

warning: unused import: `thisdoesntexistyolo::haha`
 --> src/main.rs:6:5
  |
6 | use thisdoesntexistyolo::haha;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(unused_imports)] on by default

error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
  --> src/main.rs:23:35
   |
23 |     let mut st: Something<File> = Something::new(file);
   |                                   ^^^^^^^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<_>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>>`
[...]
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`

Details

  • This issue will still occur if the imported package is real.
  • When use thisdoesntexistyolo::haha; is replaced with anything more than 2 levels deep like use thisdoesntexistyolo::a::b;, the code will compile without the error.
A-typesystem C-bug T-compiler

Most helpful comment

@leshow the problem is that there is no impl<'a, T: AsyncRead> AsyncRead for &'a T which would allow your code to work, instead there are specialized impls for a few &'a Foo with Foo being concrete types (here and here). I'm pretty sure this is why rustc goes into infinite recursion by trying to match the parameter R in your code with &PollEvented<R> which in turn matches &PollEvented<PollEvented<R>> etc.

The solution is to use &mut self.stream instead: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8e9ad05ea7a4c0f473146241a47b3e4c. It works because of impl<'a, T> AsyncRead for &'a mut T where T: AsyncRead + ?Sized.

All 14 comments

cc @shepmaster it seems a playground issue, cannot reproduce on a local machine.

I can reproduce it locally with Arch Linux's rustc:

rustc 1.32.0
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.32.0
LLVM version: 7.0

I wouldn't have used Playground if I weren't having issue on a local machine. However, I did some testing with other versions, and here are some interesting results:

  • :-1: arch rustc 1.32.0 reproduced
  • :-1: playground rustc 1.32.0 reproduced
  • :+1: rustup rustc 1.32.0 (9fda7c223 2019-01-16) cannot reproduce
  • :+1: rustup rustc 1.24.0 (4d90ac38c 2018-02-12) cannot reproduce
  • :+1: rustup rustc 1.33.0-nightly (4c2be9c97 2019-01-22) cannot reproduce

Looking at Arch Linux's build script for Rust, it appears to be a normal build with a custom config.toml.

cannot reproduce on a local machine.

Have you added both the tokio and tar crates (based on the error messages)?

Yes, adding just Tokio triggers this. I've updated the original comment.

/cc @davidtwco does this feel like anything around the external crate trait suggestions you worked on?

/cc @davidtwco does this feel like anything around the external crate trait suggestions you worked on?

I don't think so - the extern crate trait suggestions work (#55613) I've done hasn't landed (I feel like there was something like that I had done which landed, but I can't find it, so I suppose not).

hasn't landed

Oh, heh, then pretty unlikely to be related 😊! Sorry to drag you in!

Looks like the bug definitely depends on a certain package (tokio) being pulled in, but does not necessarily require a non-existent import. In my original code, importing actix-web (use actix_web::{server, Query, State, App};) was what triggered this bug.

but does not necessarily require a non-existent import

Oh, you said that in your original comment; sorry.

I tried to minimize from my codebase while applying @zhaofengli's ideas, and came to this:

[package]
name = "example"
version = "0.1.0"
authors = ["Author"]
edition = "2018"

[dependencies]
tokio-reactor = "=0.1.9"
impl Foo {}

fn bar<R>(r: &R) {
    std::io::Read::read_exact(&mut r, &mut [])
    //std::io::copy(&mut r, unimplemented!())
    //std::io::BufReader::new(r)
}

Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=a1e1abd1001d712519ac5f18f999bb3a.

Reproducible on latest stable, beta and nightly with either of the three lines in the body of foo.

All elements in this code are required to trigger the requirement evaluation overflow:

  • An unrelated impl for a non-existing type;
  • A generic function;
  • The parameter is a reference to a generic type;
  • Use of r as if it's std::io::Read.

Hope this unblocks the issue!

Minimized even more to a standalone version, reproducible with just rustc:

struct PollEvented<E> {
    phantom: std::marker::PhantomData<E>,
}

impl<'a, E> std::io::Read for &'a PollEvented<E>
where
    &'a E: std::io::Read,
{
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        unimplemented!()
    }
}

fn bar<R>(r: &R) {
    std::io::Read::read_exact(&mut r, &mut [])
    //std::io::copy(&mut r, unimplemented!())
    //std::io::BufReader::new(r)
}

which now looks very similar to https://github.com/rust-lang/rust/issues/39959#issuecomment-301342230.

Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=f0458c4cc719dcc848c4f3cc6242afba.

Having the same problem. It does not even say which file/line is the problem.
rustc 1.35.0-nightly (82e2f3ec2 2019-03-20)

❯ cargo build
   Compiling proj v0.2.0 (../proj)
error[E0275]: overflow evaluating the requirement `&tokio_reactor::poll_evented::PollEvented<_>: std::io::Write`
  |
  = help: consider adding a `#![recursion_limit="10"]` attribute to your crate
  = note: required because of the requirements on the impl of `std::io::Write` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>`
  = note: required because of the requirements on the impl of `std::io::Write` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>`
  = note: required because of the requirements on the impl of `std::io::Write` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>>`
  = note: required because of the requirements on the impl of `tokio_io::async_write::AsyncWrite` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.
error: Could not compile `proj`.

To learn more, run the command again with --verbose.

I am also having this issue, on both stable (1.33) and nightly (1.35).

error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
  |
  = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
  = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<_>`
  = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>`

With the following:

use futures::{try_ready, Async, Future, Poll};
use serde::de::DeserializeOwned;
use tokio::io::{read_exact, AsyncRead};

use std::{io, marker::PhantomData};

#[derive(Debug)]
pub struct Bar<R> {
    stream: R,
}


impl<R> Future for Bar<R>
where
    R: AsyncRead,
{
    type Item = Foo;
    type Error = io::Error;
    fn poll(&mut self) -> Poll<Self::Item, io::Error> {
        let mut buf = [0_u8; 14];
// if you comment out the following line, error goes away:
       let (rd, init) = try_ready!(read_exact(&self.stream, &mut buf).poll());

        Ok(Async::Ready(Foo { }))
    }
}

pub struct Foo {}

It appears to be read_exact that's causing the error. I've provided a minimal version of code with it breaking.

Is there anyway to get around this? The API of what I'm trying to build gets pretty gross if I can't use a generic type param.

edit: playground link https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7817e212b23d8618e9e42e4cd9061109

@leshow the problem is that there is no impl<'a, T: AsyncRead> AsyncRead for &'a T which would allow your code to work, instead there are specialized impls for a few &'a Foo with Foo being concrete types (here and here). I'm pretty sure this is why rustc goes into infinite recursion by trying to match the parameter R in your code with &PollEvented<R> which in turn matches &PollEvented<PollEvented<R>> etc.

The solution is to use &mut self.stream instead: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8e9ad05ea7a4c0f473146241a47b3e4c. It works because of impl<'a, T> AsyncRead for &'a mut T where T: AsyncRead + ?Sized.

Was this page helpful?
0 / 5 - 0 ratings