Using `?` causes rustc not to see multiple applicable impls
Open
@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(())
}
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.