Skip to content

Desugaring of struct update syntax is unnecessarily restrictive for private fieldsΒ #63538

@Osspial

Description

@Osspial

Take the following example struct:

mod module {
    #[derive(Default)]
    pub struct Foo {
        pub a: i32,
        b: u32
    }
}

Let's say you don't have access to b, and you want to create an instance of Foo with a non-default value for a. The idiomatic way to do that is with the struct update syntax, like so:

let foo = Foo {
    a: 2,
    ..Foo::default()
};

Right now, that fails with the following error:

error[E0451]: field `b` of struct `main::module::Foo` is private
  --> src/main.rs:15:7
   |
15 |     ..Foo::default()
   |       ^^^^^^^^^^^^^^ field `b` is private

That error is unintuitive since we never directly reference b in our source code. What's more, it's entirely unnecessary, since it's merely the side effect of what seems to be the current desugaring strategy, as follows:

let foo = {
    // we create temp_a before calling Foo::default() to preserve source code ordering
    let temp_a = 2;
    let temp = Foo::default();
    Foo {
        a: temp_a,
        b: temp.b
    }
};

Ideally we'd desugar to the following, which would allow the initial example to compile as expected:

let foo = {
    let temp_a = 2;
    let mut temp = Foo::default();
    temp.a = temp_a;
    temp
};

This issue proposes moving to the second method. I can't see any disadvantages to doing that, although that may just be because I'm not looking close enough.

This admittedly changes the language's behavior, but I'm submitting it as an issue instead of an RFC because the current behavior seems unintentional and this is an extremely minor change. I'll happily create an RFC if that's necessary, though.

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