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

Compiler error when trying to access function pointer in struct. #33784

Closed
damnMeddlingKid opened this issue May 22, 2016 · 8 comments
Closed

Comments

@damnMeddlingKid
Copy link

damnMeddlingKid commented May 22, 2016

running rustc 1.8.0 (db29394 2016-04-11).

I have a simple struct that contains a function pointer named get_func and when i try to access the function pointer in an implemented method i get:

hello.rs:24:14: 24:22 error: no method named `get_func` found for type `&Container` in the current scope
hello.rs:24         self.get_func(self, key)
                         ^~~~~~~~

heres the code for reproducing

use std::collections::HashMap;

struct Container {
    field: HashMap<String, i32>,
    get_func: fn(&Container, &str) -> i32
}

fn regular_get(obj: &Container, key: &str) -> i32 {
    obj.field[key]
}

impl Container {
    fn new(val: HashMap<String, i32>) -> Container {
        Container {
            field: val,
            get_func: regular_get
        }
    }

    fn get(&self, key: &str) -> i32 {
        self.get_func(self, key)
    }
}

fn main() {
    let mut c:HashMap<String, i32> = HashMap::new();
    c.insert("dog".to_string(), 123);
    let s = Container::new(c);
    println!("{} {}", 123, s.get("dog"));
}

oddly enough replacing self.get_func(self, key) with (self.get_func)(self, key) fixes the error, so I'm calling this a compiler bug.

@birkenfeld
Copy link
Contributor

It isn't a bug that you have to write (self.get_func)(self, key) - this is a conscious decision because Rust allows members and methods with the same name, so you have to be able to distinguish between calling the function pointed at by your get_func member and calling a method get_func on Container.

However, I seem to remember rustc being helpful and giving you advice when this happens -- either that was never in place for this specific case or it has been lost.

@petrochenkov
Copy link
Contributor

this is a conscious decision

[citation needed]
I strongly suspect, that the current disambiguation scheme is a case of "let's come up with some temporary hack and decide what to do later" done before 1.0 and before UFCS.

@birkenfeld
Copy link
Contributor

birkenfeld commented May 22, 2016

Fair enough. You'll admit that my version sounds better 😉

@damnMeddlingKid
Copy link
Author

Well that definitely clears things up. I didn't know that you could have members and methods with the same name, that seems a bit unecessary.

thanks @birkenfeld.

@birkenfeld
Copy link
Contributor

birkenfeld commented May 22, 2016

@damnMeddlingKid Rust has to allow this because methods don't only come from impl Type but also from traits, which can be defined in a completely different crate. Having to disambiguate explicitly avoids accidental API breaks when a method/field is added.

But it's also pretty handy for having property-like accessor methods (the recommended naming is foo() and set_foo()) and a private member foo.

@arielb1
Copy link
Contributor

arielb1 commented May 22, 2016

@petrochenkov

UFCS is not really related here - fields can't be accessed through it. Fields being in a different namespace from methods/associated items is the situation since forever, and it feels quite intentional (at least, the field-and-accessor-with-the-same-name pattern is very commonly used).

@nikomatsakis
Copy link
Contributor

@petrochenkov

I strongly suspect, that the current disambiguation scheme is a case of "let's come up with some temporary hack and decide what to do later" done before 1.0 and before UFCS.

No, it was definitely a conscious decision, but it long predates RFCs etc. There are probably some e-mails about it on the old rust-dev mailing list if you search hard enough. :)

@steveklabnik
Copy link
Member

Yup. Given that this was a conscious decision, and not a bug, closing.

birkenfeld added a commit to birkenfeld/rust that referenced this issue May 25, 2016
birkenfeld added a commit to birkenfeld/rust that referenced this issue Aug 7, 2016
bors added a commit that referenced this issue Aug 8, 2016
typeck: suggest (x.field)(...) to call struct fields even when x is a reference

Fixes: #33784

Note: This is a reopen of #33785.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants