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

Rustc suggests using private fields from RwLock when trying to use a field nested into the locked type #90340

Closed
Eijebong opened this issue Oct 27, 2021 · 3 comments
Labels
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.

Comments

@Eijebong
Copy link
Contributor

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a0e9303046930c910aaee89a9befe488

use std::sync::Arc;
use std::sync::RwLock;
pub struct Foo {
    field: u8,
}

pub struct Bar {
    foo: Foo
}

lazy_static::lazy_static! {
    pub static ref STORE: Arc<RwLock<Bar>> = Arc::new(RwLock::new(Bar {
    foo: Foo {
        field: 0,
    }}));
}

fn main() {
    let mut store = STORE.write().unwrap();
    store.field += 1;
}

The current output is:

   Compiling playground v0.0.1 (/playground)
error[E0609]: no field `field` on type `RwLockWriteGuard<'_, Bar>`
  --> src/main.rs:20:11
   |
20 |     store.field += 1;
   |           ^^^^^ unknown field
   |
help: one of the expressions' fields has a field of the same name
   |
20 |     store.lock.data.value.foo.field += 1;
   |           ++++++++++++++++++++

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

Ideally the output should look like:

   Compiling playground v0.0.1 (/playground)
error[E0609]: no field `field` on type `RwLockWriteGuard<'_, Bar>`
  --> src/main.rs:20:11
   |
20 |     store.field += 1;
   |           ^^^^^ unknown field
   |
help: one of the expressions' fields has a field of the same name
   |
20 |     store.foo.field += 1;
   |               ++++++

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

The problem does not appear without the nested struct, see here: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=1a777cefd2794d5173f0d48a31156e4f

@Eijebong Eijebong 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 Oct 27, 2021
@lqd
Copy link
Member

lqd commented Oct 27, 2021

Simplified (playground), and with another possible improvement point about the Deref impl

struct Foo {
    field: u8,
}

struct Bar {
    foo: Foo,
}

mod lock {
    pub struct Lock<T> {
        data: T,
    }
    
    impl<T> std::ops::Deref for Lock<T> {
        type Target = T;
        
        fn deref(&self) -> &Self::Target {
            &self.data
        }
    }    
}

fn main() {
    let lock = lock::Lock {
        data: Bar {
            foo: Foo { field: 0 },
        }
    };
    
    let _ = lock.field; // ERROR
    // ^ but rustc suggests to use `lock.data.foo.field` when `data` is private
    
    // Unrelated note: the error on the following line could be improved
    // by pointing into the `Deref::deref` method ?
    // let _ = lock.foo.field;
}

@hellow554
Copy link
Contributor

Looks like a duplicate of #84443 ?

@estebank
Copy link
Contributor

Current output:

error[[E0609]](https://doc.rust-lang.org/stable/error_codes/E0609.html): no field `field` on type `RwLockWriteGuard<'_, Bar>`
  --> src/main.rs:20:11
   |
20 |     store.field += 1;
   |           ^^^^^ unknown field
   |
help: one of the expressions' fields has a field of the same name
   |
20 |     store.foo.field += 1;
   |           ++++

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 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

4 participants