rust-lang / rust-lang/rust

Type inference results in `overflow evaluating the requirement`

Open
#127,411 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

The full reproducible case is here. Before committing further efforts on reducing it I would like to learn about maintainer's opinion on such issues. Whether it should be considered as bug? If so, will it be fixed straight way or need to go through some formalization first?

The skeleton is like this

f() {
    let (sender, mut receiver) = unbounded_channel();
    let (crypto_sender, mut crypto_receiver) = unbounded_channel();

    let crypto_task = run_worker(..., sender, crypto_receiver);

    let mut context = Context::<Of<_>, _> { ..., crypto_sender, ... };
    let client_task = run_with_schedule(..., context, receiver, ...);
    // let crypto_task = run_worker(..., sender, crypto_receiver);
}

If compiled like this it will fail with

error[E0275]: overflow evaluating the requirement `_: Sized`

(By the way, a minor issue here is that the trace does not properly fold the repeating steps. It also results in outputting hundreds of "long type" files (and even more if increasing recursion limit).)

If switch to define crypto_task at the commented location, it just compiles. The crypto_task and client_task are independent definitions so it is semantically same to define in either order (in my original case they are futures so even nothing executed effectively by this two definitions).

Giving annotation to the first unbounded_channel() call with at least ::<ErasedEvent<State<()>, _> makes it compile in the original order.

It has always been the case where type inference does not work in some definition order, but most of the time a "type annotation required" error is reported. Should we fix this case to the extent that at least a less confusing error is reported? On the other hand I am actually curious about the internal mechanism here:

  • As shown later in the error message compiler starts by checking for Send, but eventually get stuck in checking Sized, what's happening here?
  • How does the extra information provided by the alternative definition order help compiler bypass an infinite loop? The two seems unrelated to me, if there is supposed to be an infinite check, there will always be.

Thanks for any clarification!

Meta

rustc --version --verbose:

rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7

Also reproduced on nightly

rustc 1.81.0-nightly (524d806c6 2024-07-05)
binary: rustc
commit-hash: 524d806c62a82ecc0cf8634b94997ae506f4d6f9
commit-date: 2024-07-05
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7
Backtrace

<backtrace>

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 with the linked Rust Playground reproducer and verify the failure on the reported stable and nightly rustc versions. Compare the two definition orders and the explicit channel type annotation, then determine whether the compiler behavior or diagnostic should change.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.