-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
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: