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

E0609's "one of the expressions' fields has a field of the same name" suggestion does not consider privacy #84443

Closed
ash2x3zb9cy opened this issue Apr 22, 2021 · 7 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ash2x3zb9cy
Copy link

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d65d484826fe6e0d2d490ee1fa63052e
Given the following code:

mod lib {
    #[derive(Default)]
    pub struct Xyz { x: f32, y: f32, z: f32 }
    #[derive(Default)]
    pub struct Vec3(Xyz);
}

fn main() {
    let a: lib::Vec3 = Default::default();
    println!("{}", a.x);
}

The current output is:

   Compiling playground v0.0.1 (/playground)
error[E0609]: no field `x` on type `Vec3`
  --> src/main.rs:10:22
   |
10 |     println!("{}", a.x);
   |                      ^
   |
help: one of the expressions' fields has a field of the same name
   |
10 |     println!("{}", a.0.x);
   |                      ^^
help: a field with a similar name exists
   |
10 |     println!("{}", a.0);
   |                      ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0609`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

The suggested fixes, a.0 and a.0.x both refer to a private field, so they do not compile..

Given the following code, having implemented the suggested change:

mod lib {
    #[derive(Default)]
    pub struct Xyz { x: f32, y: f32, z: f32 }
    #[derive(Default)]
    pub struct Vec3(Xyz);
}

fn main() {
    let a: lib::Vec3 = Default::default();
    println!("{}", a.0.x);
}

The output is, correctly:

   Compiling playground v0.0.1 (/playground)
error[E0616]: field `0` of struct `Vec3` is private
  --> src/main.rs:10:22
   |
10 |     println!("{}", a.0.x);
   |                      ^ private field

error[E0616]: field `x` of struct `Xyz` is private
  --> src/main.rs:10:24
   |
10 |     println!("{}", a.0.x);
   |                        ^ private field

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0616`.
error: could not compile `playground`

To learn more, run the command again with --verbose.
@ash2x3zb9cy ash2x3zb9cy added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 22, 2021
@workingjubilee
Copy link
Member

workingjubilee commented Apr 22, 2021

This may be related to #64684. The diagnostics currently seem to be largely privacy-unaware.

@jyn514
Copy link
Member

jyn514 commented Apr 22, 2021

Is this actually wrong? I still think this is a helpful diagnostic, it means you know you have the option of making the field public.

@workingjubilee
Copy link
Member

  |
5 |     println!("{}", a.x);
  |                      ^ unknown field
  |
help: one of the expressions' fields has a field of the same name
  |
5 |     println!("{}", a.0.x);
  |                      ^^

Almost the same error is emitted if the module is in another entire crate.

@ash2x3zb9cy
Copy link
Author

The initial place I ran into this error was when the module was from another crate, yeah.

@hellow554
Copy link
Contributor

I have this piece of code:

use std::collections::{HashMap, HashSet};

pub struct A {
    items: HashSet<u32>,
}
pub struct B {
    a: A,
    map: HashMap<u32, u32>,
}
impl B {
    fn new() -> Self { todo!() }
}

fn main() {
    B::new().items.contains("");
}

which errors out with this error message:

error[E0609]: no field `items` on type `B`
  --> src/main.rs:17:14
   |
17 |     B::new().items.contains("");
   |              ^^^^^ unknown field
   |
   = note: available fields are: `a`, `map`
help: one of the expressions' fields has a field of the same name
   |
17 |     B::new().a.items.contains("");
   |              ++
help: one of the expressions' fields has a field of the same name
   |
17 |     B::new().map.base.table.table.items.contains("");
   |              +++++++++++++++++++++

e.g. it shows the internals of HashMap, which is not desired.
Maybe having an in-crate suggestion is okay, but outside supress it?

@hellow554
Copy link
Contributor

This regressed somewhere between 0e63af5...d4e3570

@rustbot modify labels: D-incorrect

@rustbot rustbot added the D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. label Sep 24, 2021
@estebank
Copy link
Contributor

Current output:

error[[E0609]](https://doc.rust-lang.org/nightly/error_codes/E0609.html): no field `x` on type `Vec3`
  --> src/main.rs:12:22
   |
12 |     println!("{}", a.x);
   |                      ^ help: a field with a similar name exists: `0`

error[[E0616]](https://doc.rust-lang.org/nightly/error_codes/E0616.html): field `0` of struct `Vec3` is private
  --> src/main.rs:16:22
   |
16 |     println!("{}", a.0.x);
   |                      ^ private field
error[[E0609]](https://doc.rust-lang.org/nightly/error_codes/E0609.html): no field `items` on type `B`
  --> src/main.rs:15:14
   |
15 |     B::new().items.contains("");
   |              ^^^^^ unknown field
   |
   = note: available fields are: `a`, `map`
help: one of the expressions' fields has a field of the same name
   |
15 |     B::new().a.items.contains("");
   |              ++

It seems like this is now correctly handled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants