Skip to content

Overflow evaluating requirement in latest nightly (1.85) #135143

@Azorlogh

Description

@Azorlogh

This code fails to compile on the latest nightly (1.85):

Playground link: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c912d455ab2679f04d8b3e8dedf694dc

pub struct Vec2;

pub trait Point {
    type S: Scalar;
}
impl Point for Vec2 {
    type S = f32;
}

pub trait Point2: Point<S = Self::S2> {
    type S2: Scalar;
}
impl Point2 for Vec2 {
    type S2 = Self::S;
}

pub trait Scalar: Default {}
impl Scalar for f32 {}

pub struct Bar<T: Default>(pub Vec<T>);
pub struct Foo<P: Point>(pub Vec<P>);

impl<P: Point2> From<Foo<P>> for Bar<P::S> {
    fn from(r: Foo<P>) -> Self {
        Self(r.0.iter().map(|_| Default::default()).collect())
    }
}

pub trait DoThing {
    fn do_thing();
}
impl DoThing for Foo<Vec2> {
    fn do_thing() {
        let _ = Bar::from(Foo::<Vec2>(vec![]));
    }
}

I expected to see this happen: It compiles without any errors

Instead, this happened: On nightly, it fails to compile with

error[E0275]: overflow evaluating the requirement `<Vec2 as Point>::S == _`

On stable (1.83.0) and beta (1.84.0-beta.6), it compiles just fine.

I encountered this bug while compiling this library, and then reduced the code until I got the example above: https://github.com/MetabuildDev/selo

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (14ee63a3c 2024-12-29)
binary: rustc
commit-hash: 14ee63a3c651bb7a243c8b07333749ab4b152e13
commit-date: 2024-12-29
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Jan 6, 2025
theemathas

theemathas commented on Jan 6, 2025

@theemathas
Contributor

My attempt at "simplifying" the reproducer code (requires an unstable feature):

#![feature(trusted_len)]

pub struct Vec2;

pub trait Point {
    type S;
}
impl Point for Vec2 {
    type S = f32;
}

pub trait Point2: Point<S = Self::S2> {
    type S2;
}
impl Point2 for Vec2 {
    type S2 = Self::S;
}

////////////////////

pub struct RepeatWith<F>(F);

impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
    type Item = A;
    fn next(&mut self) -> Option<A> {
        None
    }
}

unsafe impl<A, F: FnMut() -> A> std::iter::TrustedLen for RepeatWith<F> {}

////////////////////

trait MyFrom<T> {
    fn my_from();
}
impl<P: Point2> MyFrom<P::S> for P {
    fn my_from() {
        _ = RepeatWith(|| unimplemented!()).collect::<Vec<P::S>>();
    }
}

pub fn do_thing() {
    <Vec2 as MyFrom<_>>::my_from();
}

Playground link

Note that removing the TrustedLen impl makes the code compile on nightly, which implies that the issue is probably related to specialization.

Replacing RepeatWith with a call to std::iter::repeat_with makes the code compile on stable while still erroring on nightly. Playground link

@rustbot labels +regression-from-stable-to-nightly +A-trait-system +A-specialization

added
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Jan 6, 2025
compiler-errors

compiler-errors commented on Jan 6, 2025

@compiler-errors
Member

This seems to have regressed in #134081.

compiler-errors

compiler-errors commented on Jan 6, 2025

@compiler-errors
Member

Anyways I have a fix but I'll need to minimize this futher. I don't believe this relies on specialization.

@rustbot claim

compiler-errors

compiler-errors commented on Jan 6, 2025

@compiler-errors
Member

Overflows on nightly with no specialization:

pub struct Vec2;

pub trait Point {
    type S;
}
impl Point for Vec2 {
    type S = f32;
}

pub trait Point2: Point<S = Self::S2> {
    type S2;
}
impl Point2 for Vec2 {
    type S2 = Self::S;
}

trait MyFrom<T> {
    fn my_from();
}
impl<P: Point2> MyFrom<P::S> for P {
    fn my_from() {
        // This is just a really dumb way to force the legacy symbol mangling to
        // mangle the closure's parent impl def path *with* args. Otherwise,
        // legacy symbol mangling will strip the args from the instance, meaning
        // that we don't trigger the bug.
        let c = || {};
        let x = Box::new(c) as Box<dyn Fn()>;
    }
}

fn main() {
    <Vec2 as MyFrom<_>>::my_from();
}
removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Jan 6, 2025
removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Jan 7, 2025
added 2 commits that reference this issue on Jan 7, 2025
de304e8
3e12d4d
added a commit that references this issue on Jan 8, 2025
fe0f6fe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Participants

    @compiler-errors@apiraino@theemathas@saethlin@Azorlogh

    Issue actions

      Overflow evaluating requirement in latest nightly (1.85) · Issue #135143 · rust-lang/rust