Skip to content

Method lookup goes down the auto-deref rabbit hole when it doesn't need to #19509

Open
@tomjakubowski

Description

@tomjakubowski

Here's a pathological example of two types, each implementing Deref on the other:

use std::ops::Deref;
use std::rc::Rc;

struct Foo;
struct Bar;

impl Deref<Bar> for Foo {
    fn deref<'a>(&'a self) -> &'a Bar {
        panic!()
    }
}

impl Deref<Foo> for Bar {
    fn deref<'a>(&'a self) -> &'a Foo {
        panic!()
    }
}

fn main() {
    let foo = Rc::new(Foo);
    let foo2 = foo.clone(); 
}
<anon>:21:20: 21:27 error: reached the recursion limit while auto-dereferencing alloc::rc::Rc<Foo> [E0055]
<anon>:21     let foo2 = foo.clone();
                             ^~~~~~~

Even though Rc<T> implements Clone and thus has a clone method, method resolution still tries to look up methods available via deref. This also happens for trying to call inherent methods on a Foo directly (without using Rc).

Update:

Modern code on playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2ca8f056b69c0cd8e4ce0365a6356f02

Current error (as of 2024):

error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
  --> src/main.rs:23:20
   |
23 |     let foo2 = foo.clone(); 
   |                    ^^^^^ deref recursion limit reached
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`playground`)

For more information about this error, try `rustc --explain E0055`.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.P-lowLow priorityT-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions