rust-lang / rust-lang/rust

Double same-bound `where` clause causes failed type inference

Open
#132,667 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-trait-system C-bug E-needs-investigation T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I came across this scenario where having two functions with the same where-bounds causes type inference failure:

pub fn foo<S>(_: S) where String: From<S> {}
pub fn bar<S>(s: S) where String: From<S> {
    // Mismatched types error!
    foo(String::from(s)); 
}

I would expect the type inference to hold up and allow for calling foo with a String constructed in bar. Instead it fails with a mismatched types error (E0308) saying expected type parameter `S`, found `String`

Notably, ANY String or &str constructed in bar and passed to foo will fail type inference. For example:

pub fn baz<S>(_: S) where String: From<S> {
    // Mismatched types error!
    foo(""); 
}

pub fn bam<S>(_: S) where String: From<S> {
    // Mismatched types error!
    let s: String = "".to_owned();
    foo(s); 
}

Some examples of similar scenarios that work, but show that there shouldn't be anything wrong with the actual operation (particularly bap):

pub fn bam<S>(s: S) where String: From<S> {
    // OK!
    foo(s); 
}
pub fn bap<S>(s: S) where String: From<S> {
    // OK!
    foo::<String>(String::from(s)); 
}
pub fn bao() {
    // OK!
    let s: String = "".to_owned();
    foo(s); 
}

// Strangely, inverting the From bound to an Into bound fixes things
pub fn foo2<S>(_: S) where S: Into<String> {}
pub fn bar2<S>(s: S) where String: From<S> {
    // OK!
    foo2(String::from(s)); 
}
Meta

This occurs on stable (1.82.0), beta (1.83.0-beta.4 // 2024-11-02 67512dee7a470ea7cdd6), and nightly (1.83.0-nightly // 2024-11-03 b8c8287a229cd79604aa) in debug and release modes.

Full Playground Link

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 compare the failing calls with the examples that compile. Investigate type inference around the duplicated String: From<S> bounds and the differing Into<String> form. Done means the reported valid calls no longer produce E0308, with the behavior covered by a compiler regression test.

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
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.