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

feature: Add 'destructure struct binding' assist #13997

Closed
wants to merge 3 commits into from

Conversation

IFcoltransG
Copy link

Adds an assist to destructure a struct in a binding. This is part of #8673, but more functionality is needed to bring it in line with tuple bindings. Similar to #9855 for tuple bindings, except that this pull does not yet edit the usages of the fields, just the original binding to an identifier.

struct Struct { a: u8, b: u8 }

fn main() {
    let $0x = Struct { a: 1, b: 2 };
}

->

struct Struct { a: u8, b: u8 }

fn main() {
    let Struct { a: $0_a, b: _b } = Struct { a: 1, b: 2 };
}

Implemented:

  • Destructuring record structs, tuple structs and unit structs
  • Copying mut and ref from the original identifier to the fields of the struct
  • Destructuring within any sort of binding, inline

Not implemented:

  • Smart variable naming to ensure no shadowing
  • Editing usages
  • Destructuring using a sub-pattern
  • Omitting private and #[non_exhaustive] fields with ..

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 21, 2023
@lnicola lnicola added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 13, 2023
@Veykril Veykril added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 25, 2023
@Veykril
Copy link
Member

Veykril commented Aug 15, 2023

I'm cleaning up our PR backlog right now, if you are coming back to this feel free to re-open.

@Veykril Veykril closed this Aug 15, 2023
bors added a commit that referenced this pull request Feb 27, 2024
feature: Add `destructure_struct_binding`

Adds an assist for destructuring a struct in a binding (#8673). I saw that #13997 has been abandoned for a while, so I thought I'd give it a go.

## Example

```rust
let foo = Foo { bar: 1, baz: 2 };
let bar2 = foo.bar;
let baz2 = foo.baz;
let foo2 = foo;

let fizz = Fizz(1, 2);
let buzz = fizz.0;
```
becomes
```rust
let Foo { bar, baz } = Foo { bar: 1, baz: 2 };
let bar2 = bar;
let baz2 = baz;
let foo2 = todo!();

let Fizz(_0, _1) = Fizz(1, 2);
let buzz = _0;
```

More examples in the tests.

## What is included?

- [x] Destructure record, tuple, and unit struct bindings
- [x] Edit field usages
- [x] Non-exhaustive structs in foreign crates and private fields get hidden behind `..`
- [x] Nested bindings
- [x] Carry over `mut` and `ref mut` in nested bindings to fields, i.e. `let Foo { ref mut bar } = ...` becomes `let Foo { bar: Bar { baz: ref mut baz } } = ...`
- [x] Attempt to resolve collisions with other names in the scope
- [x] If the binding is to a reference, field usages are dereferenced if required
- [x] Use shorthand notation if possible

## Known limitations

- `let foo = Foo { bar: 1 }; foo;` currently results in `let Foo { bar } = Foo { bar: 1 }; todo!();` instead of reassembling the struct. This requires user intervention.
- Unused fields are not currently omitted. I thought that this is more ergonomic, as there already is a quick fix action for adding `: _` to unused field patterns.
bors added a commit that referenced this pull request Feb 29, 2024
feature: Add `destructure_struct_binding`

Adds an assist for destructuring a struct in a binding (#8673). I saw that #13997 has been abandoned for a while, so I thought I'd give it a go.

## Example

```rust
let foo = Foo { bar: 1, baz: 2 };
let bar2 = foo.bar;
let baz2 = foo.baz;
let foo2 = foo;

let fizz = Fizz(1, 2);
let buzz = fizz.0;
```
becomes
```rust
let Foo { bar, baz } = Foo { bar: 1, baz: 2 };
let bar2 = bar;
let baz2 = baz;
let foo2 = todo!();

let Fizz(_0, _1) = Fizz(1, 2);
let buzz = _0;
```

More examples in the tests.

## What is included?

- [x] Destructure record, tuple, and unit struct bindings
- [x] Edit field usages
- [x] Non-exhaustive structs in foreign crates and private fields get hidden behind `..`
- [x] Nested bindings
- [x] Carry over `mut` and `ref mut` in nested bindings to fields, i.e. `let Foo { ref mut bar } = ...` becomes `let Foo { bar: Bar { baz: ref mut baz } } = ...`
- [x] Attempt to resolve collisions with other names in the scope
- [x] If the binding is to a reference, field usages are dereferenced if required
- [x] Use shorthand notation if possible

## Known limitations

- `let foo = Foo { bar: 1 }; foo;` currently results in `let Foo { bar } = Foo { bar: 1 }; todo!();` instead of reassembling the struct. This requires user intervention.
- Unused fields are not currently omitted. I thought that this is more ergonomic, as there already is a quick fix action for adding `: _` to unused field patterns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants