Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method calls with custom receiver types "forget" their type arguments #8100

Closed
nightkr opened this issue Mar 18, 2021 · 1 comment · Fixed by #9090
Closed

Method calls with custom receiver types "forget" their type arguments #8100

nightkr opened this issue Mar 18, 2021 · 1 comment · Fixed by #9090
Labels
A-ty type system / type inference / traits / method resolution S-actionable Someone could pick this issue up and work on it right now

Comments

@nightkr
Copy link

nightkr commented Mar 18, 2021

Methods with custom receiver types (that is, of the shape fn foo(self: Box<Self>) rather than fn foo(&self)) "forget" Self's type arguments, when inferring the return type. However, this only happens when using the method call syntax (foo.bar()), UFCS calls (Foo::bar(foo)) work fine.

This makes it quite a bit more annoying to interact with things that use Pin, such as Futures.

Repro

Open https://gitlab.com/teozkr/repros/-/blob/rust-analyzer/receiver-confusion/src/main.rs in an editor with RA variable type inlays enabled, or view https://teozkr.gitlab.io/repros/rust-analyzer/receiver-confusion/main.rs.html.

You'd expect every pair of variables to be inferred to have the same type (&i32, &i32, and &Foo<i32> respectively), but currently the method call variants are instead inferred as &i32, &{unknown}, and &Foo<{unknown}>.

I'm using d0805c6

@Veykril Veykril added A-ty type system / type inference / traits / method resolution S-actionable Someone could pick this issue up and work on it right now labels Mar 18, 2021
@jonas-schievink
Copy link
Contributor

jonas-schievink commented Mar 19, 2021

Inlining a reproduction:

struct Foo<T>(T);

impl<T> Foo<T> {
    fn get_inner<'a>(self: &'a Box<Self>) -> &'a T {
        &self.0
    }

    fn get_self<'a>(self: &'a Box<Self>) -> &'a Self {
        &*self
    }
}

fn main() {
    let boxed = Box::new(Foo(0_i32));

    let bad1 = boxed.get_inner();
    let good1 = Foo::get_inner(&boxed);

    let bad2 = boxed.get_self();
    let good2 = Foo::get_self(&boxed);
}

bad1 is inferred as &{unknown} (should be &i32), bad2 as &Foo<{unknown}> (should be &Foo<i32>)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ty type system / type inference / traits / method resolution S-actionable Someone could pick this issue up and work on it right now
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants