-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Description
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.
Activity
birkenfeld commentedon May 22, 2016
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 yourget_func
member and calling a methodget_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 commentedon May 22, 2016
[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 commentedon May 22, 2016
Fair enough. You'll admit that my version sounds better 😉
damnMeddlingKid commentedon May 22, 2016
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 commentedon 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()
andset_foo()
) and a private memberfoo
.arielb1 commentedon 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 commentedon May 24, 2016
@petrochenkov
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 commentedon May 24, 2016
Yup. Given that this was a conscious decision, and not a bug, closing.
typeck: suggest (x.field)(...) to call struct fields even when x is a…
typeck: suggest (x.field)(...) to call struct fields even when x is a…
Auto merge of #35456 - birkenfeld:issue-33784, r=nikomatsakis