rust-lang / rust-lang/rust

Type mismatch when generics involved, works with new solver

Open
#141,792 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug fixed-by-next-solver T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

use std::convert::{Infallible, TryInto};

struct A;

#[derive(Debug)]
struct E;

impl From<Infallible> for E {
    fn from(_: Infallible) -> E {
        unreachable!()
    }
}

fn not_working<T>(t: T) -> Result<(), E>
where
    T: TryInto<A>,
    E: From<T::Error>,
{
    let a: A = t.try_into()?;
    // Uncomment the turbofish to make it compile
    breaking /* ::<A> */(a)
}

fn breaking<T>(t: T) -> Result<(), E>
where
    T: TryInto<A>,
    E: From<T::Error>,
{
    let a = t.try_into()?;
    Ok(())
}

I expected to see this happen: the code should compile, the a inside not_working has a type of A and the invocation of breaking is expected to use T = A.

Instead, this happened: the code does not compile with the following error:

error[E0271]: type mismatch resolving `<A as TryInto<A>>::Error == <T as TryInto<A>>::Error`
  --> src/lib.rs:21:5
   |
21 |     breaking /* ::<A> */(a)
   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `Infallible`
   |
   = note: expected associated type `<T as TryInto<A>>::Error`
                         found enum `Infallible`
help: consider constraining the associated type `<T as TryInto<A>>::Error` to `Infallible`
   |
16 |     T: TryInto<A, Error = Infallible>,
   |                 ++++++++++++++++++++

If the function which invokes breaking creates the instance of A without using generics, the code compiles:

fn working(a: A) -> Result<(), E> {
    breaking(a)
}

Some interesting things:

  • if breaking is invoked specifying the generic with the turbofish notation, the program compiles
  • the code compiles in nightly if the -Z next-solver is used
  • it is broken at least since 1.34 (I tested this version because of the introduction of TryInto
  • it is broken for all editions (but it should compile for all of them)

I am not sure if it could be related to https://github.com/rust-lang/rust/issues/139531.

Meta

rustc --version --verbose:

rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-unknown-linux-gnu
release: 1.87.0
LLVM version: 20.1.1

It is also broken on nightly:

cargo 1.89.0-nightly (68db37499 2025-05-22)
release: 1.89.0-nightly
commit-hash: 68db37499f2de8acef704c73d9031be6fbcbaee4
commit-date: 2025-05-22
host: x86_64-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.2 vendored)
libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.5.0)
ssl: OpenSSL 3.5.0 8 Apr 2025
os: Arch Linux Rolling Release [64-bit

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 reproducing the example in src/lib.rs with rustc 1.87.0, then compare its behavior with nightly using -Z next-solver and with the explicit turbofish. Trace the generic calls to not_working and breaking and add a regression test showing that the invocation without the turbofish compiles under the existing solver.

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
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.