rust-lang / rust-lang/rust

Using `?` causes rustc not to see multiple applicable impls

Open
#118,033 2 comments 0 reactions 1 assignee View on GitHub

@max-niederman is already working on this.

Since Nov 19, 2023.

A-diagnostics C-bug T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Given this code:

struct Foo;

impl From<()> for Foo {
    fn from(_: ()) -> Self {
        Self
    }
}

impl From<String> for Foo {
    fn from(_: String) -> Self {
        Self
    }
}

struct Bar;

impl Bar {
    fn get<T>(&self) -> Result<T, ()> {
        todo!()
    }
}

fn foo() {
    _ = Foo::from(Bar.get().unwrap());
}

... the compiler correctly rejects it, saying:

error[E0283]: type annotations needed
  --> src/lib.rs:24:23
   |
24 |     _ = Foo::from(Bar.get().unwrap());
   |         ---           ^^^ cannot infer type of the type parameter `T` declared on the method `get`
   |         |
   |         type must be known at this point
   |
note: multiple `impl`s satisfying `Foo: From<_>` found
  [...]

... but swapping .unwrap() with ? causes it to accept the code, (arbitrarily?) picking the () impl:

fn foo() -> Result<(), ()> {
    _ = Foo::from(Bar.get()?);
    Ok(())
}

(playground link)

Spotted in the wild at https://github.com/launchbadge/sqlx/issues/2728 - there it looks like the compiler picks the impl randomly, but in my experiments above I haven't been able to force it to pick anything other than ().

Checked on current stable (1.74.0), beta (1.75.0-beta.1) and nightly (2023-11-15).

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.