-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error: overflow evaluating the requirement <_ as core::iter::Iterator>::Item
#23707
Comments
Can you show some code that reproduces this? |
Alright, I think I've found the culprit (playpen link). /// A trait that produces a clone of the previously yielded element along
/// with the current element.
pub trait ZipPrev: Iterator + Sized {
fn zip_prev(self) -> Items<Self::Item, Self> {
Items {
maybe_prev: None,
iter: self,
}
}
}
/// The iterator produced by the zip_prev method.
pub struct Items<A, I> {
maybe_prev: Option<A>,
iter: I,
}
impl<I> Iterator for Items<I::Item, I>
where
I: Iterator,
I::Item: Clone,
{
type Item = (I::Item, Option<I::Item>);
#[inline]
fn next(&mut self) -> Option<(I::Item, Option<I::Item>)> {
let Items { ref mut iter, ref mut maybe_prev } = *self;
if let Some(item) = iter.next() {
let old_maybe_prev = maybe_prev.take();
*maybe_prev = Some(item.clone());
Some((item, old_maybe_prev))
} else {
None
}
}
}
impl<I> ZipPrev for I
where
I: Iterator,
I::Item: Clone {}
fn main() {} Perhaps it's the implementation of |
We are having similar issues with rust-sessions. Here is the cooked down version: use std::marker::{PhantomData, PhantomFn};
struct Chan<T> ( PhantomData<T> );
struct Eps;
struct Send<A,R> ( PhantomData<(A, R)> );
trait Dual: PhantomFn<Self> {}
impl Dual for (Eps, Eps) {}
impl <A, T> Dual for (Send<A, T>, Send<A, T>)
where (T, T): Dual {}
fn request<R, S> (rx: Chan<R>) where (R, S): Dual {
borrow_request(&rx)
}
fn borrow_request<R, S> (rx: &Chan<R>) where (R, S): Dual {} That code compiles with cc @laumann |
Here's another example. This fails with overflow evaluating '_ : core::marker::Sized'. Commenting one line in main and uncommenting its alternative makes the code compile. https://gist.github.com/Gerstacker/b402c38381604e2ff117 In playpen: |
What's the status of this? The example @Munksgaard posts can be "fixed" by adding explicit type annotations to the call to fn request<R, S> (rx: Chan<R>) where (R, S): Dual {
borrow_request::<R, S>(&rx)
} but it's rather unsatisfactory, since whoever calls |
This annotation workaround fixed mine as well, letting rustc get far enough to expose an embarrassing problem in my code. |
It seems like PR #23580 is the cause of this issue. Perhaps @nikomatsakis could comment on whether or not this is intentional? |
This no longer ICEs. |
Confirmed 👍 |
I'm completely new to working with libstd, but would be happy to take this on under a mentor. |
I'm also getting this error in a particular case where I can't find a workaround (at least, not yet). I would also be interested in taking this on. |
Here's a boiled down example that exhibits the same error, and I think it is pretty minimal. As I boiled it down the exact trait bounds on the requirement in the error message reduced until it became trait Foo<T> {
type Out;
}
impl Foo<()> for () {
type Out = ();
}
//Removing this impl stops the error, despite being unrelated to the call.
impl<A, B> Foo<(A, B)> for () where (): Foo<A, Out=B> {
type Out = ();
}
fn bar<T>(_: T) where (): Foo<T> {}
fn main() {
bar(());
} playpen link: http://is.gd/VBG9Sp In the case where this popped up that this example originates from, the function call involved cannot be worked around by giving explicit type parameters (in this example, |
Perhaps @nikomatsakis could comment on which code in the compiler is likely to be relevant to this issue, given the reduced example I've posted? |
@dylanede note that you have a recursive impl there, so while the error message could be improved, the fact that this doesn't work isn't a bug. Perhaps try structuring your traits differently? |
Hmm. I'm not sure the extent to which this is a bug -- I'm also not sure if the minified example will turn out to be representative of the other cases where this crops up. Overflow is tricky like that. I have to work through that impl in my head -- it is at least somewhat recursive, and the fact that it doesn't apply in one particular case isn't necessarily relevant, since the compiler may encounter an overflow just trying to figure out if it applies (this is presumably happening before we have processing the argument type, and hence we don't know that it cannot apply yet). It seems plausible we might rejigger the trait matching mechanism to make the minified example work, basically by treating the overflow case as ambiguous -- later on we might know that the argument is In any case, certainly the error message can be vastly improved (and #30533 will help here, by giving access to the complete backtrace). In short, I'm not sure why this issue was marked as |
@Manishearth How is the recursion a problem? |
@nikomatsakis the regression test for the original ICE is the easy part |
@dylanede the overflow is in the definition of That type of recursive impl usually doesn't work in Rust. |
OK, I'll see if I can at least understand the relevant code. |
@dylanede feel to ping me on IRC ( |
Here's a reduction that shows where I am hitting this in ndarray. The idea is to implement both addition of arrays and addition of array with scalar. Playground link to code. use std::ops::{Add, DerefMut};
#[derive(Clone)]
struct Array<S>(S);
impl<A, S> Add for Array<S>
where A: Clone + Add<Output=A>,
S: DerefMut<Target=[A]>,
{
type Output = Self;
fn add(self, rhs: Self) -> Self {
panic!()
}
}
impl<A, S> Add<A> for Array<S>
where A: Clone + Add<Output=A>,
S: DerefMut<Target=[A]>,
{
type Output = Self;
fn add(self, rhs: A) -> Self {
panic!()
}
}
fn main() {
}
// error: overflow evaluating the requirement `<_ as core::ops::Deref>::Target` My current workaround looks approximately like the following. It's suboptimal since it requires a marker trait on all allowable scalars // workaround
trait ScalarMarker { }
impl<A, S, B> Add<B> for Array<S>
where A: Clone + Add<B, Output=A>,
S: DerefMut<Target=[A]>,
B: ScalarMarker
{
type Output = Self;
fn add(self, rhs: B) -> Self {
panic!()
}
} |
Triage: @bluss example still overflows. |
Not sure if this is relevant, but a popular lib extern crate tokio_core;
extern crate tokio_io;
use std::{borrow::Borrow, rc::Rc};
use tokio_core::net::TcpStream;
use tokio_io::io::read_exact;
fn read_one(conn: Rc<TcpStream>) {
read_exact(conn.borrow(), [0u8]);
} The workaround is to use read_exact(&*conn,[0u8]); But for new users this will just get them confused. |
Here's another one that overflows. Is it supposed to? (and if not, is there a workaround?) trait X {
type Item;
}
trait Y {
type Item: X;
}
impl<T: Y> X for T {
type Item = <Self::Item as X>::Item;
}
// error[E0275]: overflow evaluating the requirement `<T as X>::Item`
// --> src/main.rs:9:12
// |
// 9 | impl<T: Y> X for T {
// | ^ ^ |
Another somehow simple example: use std::borrow::Cow;
enum Test <'a> {
Int(u8),
Array(Cow<'a, [Test<'a>]>),
} |
It seems like this is happening whenever an associated type is referenced while it's still evaluating the impl it's defined in, here is a small example that seems like it should be fine: trait TraitWithAssociatedType {
type AssociatedType;
}
trait AnyTrait { }
struct StructWithImpl;
struct AnyStruct;
impl TraitWithAssociatedType for StructWithImpl where Self::AssociatedType: AnyTrait {
type AssociatedType = AnyStruct;
} Intuitively it seems like the overflow might be comming from infinite recursion when it tries to check the In this case replacing |
…atthiaskrgr Delete `tests/crashes/23707.rs` because it's flaky It's conditioned on `only-x86_64` because it doesn't reliably fail on other platforms, it's optimization dependent and failed to ICE post-PGO in <rust-lang#132300 (comment)>. Remove this test for now without prejudice against relanding the test in a more reliable form. I removed the `S-bug-has-test` label from rust-lang#23707. r? compiler
Rollup merge of rust-lang#132312 - jieyouxu:delete-crashes-23707, r=matthiaskrgr Delete `tests/crashes/23707.rs` because it's flaky It's conditioned on `only-x86_64` because it doesn't reliably fail on other platforms, it's optimization dependent and failed to ICE post-PGO in <rust-lang#132300 (comment)>. Remove this test for now without prejudice against relanding the test in a more reliable form. I removed the `S-bug-has-test` label from rust-lang#23707. r? compiler
The error suggests adding a recursion requirement to my crate root
It continues to recommend doubling the recursion limit until I've raised it so high that rustc itself overflows it's stack
Here's a link to the repository that is failing to build in case you would like to give it a go.
The error only appeared in the latest nightly for rustc (I'm fairly sure the crate was building fine before I updated). Here's the version of the nightly I've just downloaded which seems to have caused the failure:
The text was updated successfully, but these errors were encountered: