-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Trying to access public function with same name as private field gives confusing error #26472
Comments
CC me |
Maybe fixed by #26305? |
It is not, @Ms2ger , I can confirm same error with |
cc @Nashenas88 want to try looking into this? |
@Manishearth, that seems tricky. The error is correct, but maybe we could add a useful note here. I'll take a look later today. |
This looks fixable, though I think I've also found a bug in #26305. I could potentially be recommending private functions there. A common solution could fix both of these issues, but the code for this error is in librustc_privacy, and the code for #26305 is in librustc_typeck. Where should I put the fix so it's accessible by both folders? |
I was wrong, it's not so simple. Something that didn't pop into my head until later is the fact that Rust allows a struct field and a struct implementation's function to have the same name. Most languages don't allow this. I thought the code between the two could be shared, but the use cases are very different from the compiler's perspective. I played around with the following on the playground to see what the existing behavior is: #![feature(core, unboxed_closures)]
mod inner {
pub struct Dog {
pub x: usize,
pub c: Barking,
d: Barking,
}
impl Dog {
pub fn new() -> Dog {
Dog {
x: 5,
c: Barking,
d: Barking,
}
}
pub fn d() -> usize {
3
}
}
pub struct Barking;
impl Barking {
pub fn woof(&self) -> usize {
3
}
}
impl Fn<()> for Barking {
extern "rust-call" fn call(&self, _: ()) -> usize {
self.woof()
}
}
impl FnMut<()> for Barking {
extern "rust-call" fn call_mut(&mut self, _: ()) -> usize {
self.woof()
}
}
impl FnOnce<()> for Barking {
type Output = usize;
extern "rust-call" fn call_once(self, _: ()) -> usize {
self.woof()
}
}
}
fn main() {
let dog = inner::Dog::new();
let _ = dog.x();
let _ = dog.c();
let _ = (dog.c)();
let _ = dog.d();
let _ = (dog.d)();
} This gives the following output on nightly:
(playground here) If I add fn main() {
let dog = inner::Dog::new();
// let _ = dog.x();
// let _ = dog.c();
// let _ = (dog.c)();
let _ = dog.d();
let _ = (dog.d)();
} I get this error:
So the private errors are checked on a separate pass. I'd like to use the same style of note message as the static methods note. I just need to see how complicated it will be to get the type's function list from librustc_privacy |
FYI: I haven't been had the time to work on this issue as thoroughly as I'd have liked to. Anyone is free to pick this up. |
For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: rust-lang#26472 NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
When trying to access the len of a Vec I forgot the parens. This led to an error message about using a private field which confused me. (Thanks to the IRC for helping me find the problem!)
Code:
Error:
The text was updated successfully, but these errors were encountered: