rust-lang / rust-lang/rust

Trivial bounds with associated types regression

Open
#134,238 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-trait-system C-bug fixed-by-next-solver P-low regression-from-stable-to-stable T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code

I tried writing some macro code that in some cases generates code similar to:

pub trait A {
    type X;
}

pub trait B: A<X = Self::Y> {
    type Y: C;
}

impl<L> A for L {
    type X = L;
}

pub trait C {}

impl C for () {}

impl<T> B for T 
where
    T: A,
    T::X: C,
{
    type Y = T::X;
}

fn demo() where for<'a> (): B {}

I expected to see this happen: The code should compile without error.

Instead, this happened: The following compile error happens.

error[E0284]: type annotations needed
  --> <source>:25:1
   |
25 | fn demo() where for<'a> (): B {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
   |
   = note: cannot satisfy `<() as B>::Y == _`

error[E0284]: type annotations needed
  --> <source>:25:29
   |
25 | fn demo() where for<'a> (): B {}
   |                             ^ cannot infer type
   |
   = note: cannot satisfy `<() as B>::Y == _`

Discussing with @compiler-errors some it would appear https://github.com/rust-lang/rust/pull/122791 is the cause of the change. The above code does compile if it isn't a trivial bound. For example when you do this instead:

fn demo<T>() where T: B {}

fn other() {
    demo::<()>();
}

For more context on 1.78.0 and before if you remove the for<'a> you get the following.

error[E0271]: type mismatch resolving `<() as A>::X == <() as B>::Y`
  --> <source>:25:17
   |
25 | fn demo() where (): B {}
   |                 ^^^^^ type mismatch resolving `<() as A>::X == <() as B>::Y`
   |
note: expected this to be `()`
  --> <source>:10:14
   |
10 |     type X = L;
   |              ^
   = note:    expected unit type `()`
           found associated type `<() as B>::Y`
   = help: consider constraining the associated type `<() as B>::Y` to `()`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
   = help: see issue #48214
Version it worked on

It most recently worked on: 1.78.0

Version with regression

All versions including 1.79.0 and after. Specifically starting with nightly-2024-04-04 (found with a bisection).

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the provided associated-types and trivial-bounds reproducer, comparing behavior across the stated Rust versions. Review PR #122791 for the suspected regression; done means the example compiles as expected without weakening the demonstrated bounds behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.