Skip to content

Suggest the correct name if using a struct literal and struct update syntax #105398

Open
@alexwlchan

Description

@alexwlchan

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

#[derive(Debug)]
struct Shape<'a> {
    colour: &'a str,
    sides: usize,
}

fn main() {
    let blue_triangle = Shape {
        colour: "blue",
        sides: 3,
    };

    println!("The blue triangle is {:?}", blue_triangle);

    let blue_square = {
        sides: 4,
        ..blue_triangle
    };

    println!("The blue square is {:?}", blue_square);
}

The current output is:

error: struct literal body without path
  --> src/main.rs:15:23
   |
15 |       let blue_square = {
   |  _______________________^
16 | |         sides: 4,
17 | |         ..blue_triangle
18 | |     };
   | |_____^
   |
help: you might have forgotten to add the struct literal inside the block
   |
15 ~     let blue_square = { SomeStruct {
16 |         sides: 4,
17 |         ..blue_triangle
18 ~     } };
   |

Ideally the output should look like:

 error: struct literal body without path
   --> src/main.rs:15:23
    |
 15 |       let blue_square = {
    |  _______________________^
 16 | |         sides: 4,
 17 | |         ..blue_triangle
 18 | |     };
    | |_____^
    |
 help: you might have forgotten to add the struct literal inside the block
    |
 15 ~     let blue_square = { SomeStruct {
 16 |         sides: 4,
 17 |         ..blue_triangle
 18 ~     } };
    |
+help: perhaps you intended to use this struct literal:
+   |
+15 ~     let blue_square = Shape {
+16 |         sides: 4,
+17 |         ..blue_triangle
+18 |     };
+   |

You'd want to be somewhat conservative here, but in this case:

  • the struct I'm passing in ..blue_triangle is a Shape
  • the field I'm updating is also valid on Shape

For comparison with a similar construction in another language: TypeScript has a spread operator which is similar to Rust's struct update syntax, and it recognises that I'm overriding a field here without asking me to respecify the type. See TypeScript Playground example

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions