Skip to content

Functional record update: private fields should not throw errors if not explicitly used in literals #70564

Open
@RReverser

Description

@RReverser

I tried this code:

mod module {
    #[derive(Default)]
    pub struct S {
        pub public_field: u32,
        _private_field: u32,
    }
}

use module::S;

pub fn f() -> S {
    S {
        public_field: 42,
        ..S::default()
    }
}

I expected to see this happen: code compiles successfully.

Instead, this happened: rustc throws an error

error[E0451]: field `_private_field` of struct `module::S` is private

  --> <source>:14:11

   |

14 |         ..S::default()

   |           ^^^^^^^^^^^^ field `_private_field` is private

As a user, I field this confusing, because I'm not trying to access or set the private field explicitly anywhere in the literal.

Meta

Applies to all known rustc versions.

I understand why this happens in principle, if the literal is desugared literally (no pun intended) to:

let s_rest = S::default();
let s = S {
  public_field: 42,
  _private_field: s_rest.private_field,
};

However, it seems that this code could be equally expanded to:

let mut s = S::default();
s.public_field = 42;
let s = s;

This way an immutable literal could be used with many more kinds of structures without users manually resorting to the temporarily-mutable variable as in the 2nd example.

Do I miss some other difference between the two that would break some existing usecases if the implementation is changed?

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions