rust-lang / rust-lang/rust

Type inference failure in the presence of multiple `Deref` impls

Open
#122,579 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-inference C-bug T-types
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

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.