Type inference failure in the presence of multiple `Deref` impls
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
In this minimized test case, we call .clone() on an object of type Obj<?T> where ?T is an inference variable, and ideally we would expect the result to also have type Obj<?T> given the method signature of Clone::clone, which is then unified with the target type Obj<u8> and all is well. However, the presence of the two Deref impls for unrelated types causes (I think) the argument to .clone() to have unknown type, resulting in an error saying that clone() is not found on Obj<_> (even though there is a blanket implementation for all Obj<A>), and then another error (printed first but I think generated second) saying that it cannot infer the type of the input to clone().
use std::{marker::PhantomData, ops::Deref};
pub struct Obj<A: ?Sized>(PhantomData<A>);
impl<A: ?Sized> Clone for Obj<A> {
fn clone(&self) -> Self {
panic!()
}
}
impl Deref for Obj<u16> {
type Target = ();
fn deref(&self) -> &Self::Target {
panic!()
}
}
impl Deref for Obj<u32> {
type Target = ();
fn deref(&self) -> &Self::Target {
panic!()
}
}
fn main() {
let x: Obj<u8> = Obj(PhantomData).clone();
// ^^^^^ cannot infer type
// ^^^^^ method not found in `Obj<_>`
}
I expected to see this happen: no error
Instead, this happened:
Checking rust-test v0.1.0 (/home/mario/Documents/rust-test)
error[E0282]: type annotations needed
--> src/main.rs:26:39
|
26 | let x: Obj<u8> = Obj(PhantomData).clone();
| ^^^^^ cannot infer type
error[E0599]: no method named `clone` found for struct `Obj<_>` in the current scope
--> src/main.rs:26:39
|
3 | pub struct Obj<A: ?Sized>(PhantomData<A>);
| ------------------------- method `clone` not found for this struct
...
26 | let x: Obj<u8> = Obj(PhantomData).clone();
| ^^^^^ method not found in `Obj<_>`
|
note: method is available for `Obj<&mut _>`
--> /home/mario/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/clone.rs:160:5
|
160 | fn clone(&self) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: method is available for `Obj<&_>`
--> /home/mario/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/clone.rs:160:5
|
160 | fn clone(&self) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: method is available for `Obj<_>`
--> /home/mario/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/clone.rs:160:5
|
160 | fn clone(&self) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `clone`, perhaps you need to implement it:
candidate #1: `Clone`
help: trait `Clone` which provides `clone` is implemented but not in scope; perhaps you want to import it
|
1 + use std::clone::Clone;
|
Some errors have detailed explanations: E0282, E0599.
For more information about an error, try `rustc --explain E0282`.
error: could not compile `rust-test` (bin "rust-test") due to 2 previous errors
Meta
rustc --version --verbose:
rustc 1.78.0-nightly (c67326b06 2024-03-15)
binary: rustc
commit-hash: c67326b063bd27ed04f306ba2e372cd92e0a8751
commit-date: 2024-03-15
host: x86_64-unknown-linux-gnu
release: 1.78.0-nightly
LLVM version: 18.1.0
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.
Research direction
Start by reproducing the minimized example in src/main.rs with the reported nightly rustc version and compare the expected and actual diagnostics. Then trace the compiler's method lookup and type inference handling for the two Deref implementations and the generic Clone impl. Done means the example compiles without inference or method-not-found errors.
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
- 42/100