# Name aliases for struct fields and enum variants

**URL:** https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041
**Category:** language design
**Created:** [June 17, 2024, 6:12pm UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041 "2024-06-17T18:12:33Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [June 17, 2024, 6:12pm UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/1 "2024-06-17T18:12:33Z")

</div>

Rust has a few useful features for making backwards-compatible API changes — type aliases, `pub use`, default method implementations in traits, and simply ability for inherent methods to forward calls to another method, and all of that can be shoved under `#[doc(hidden)]`. Very nice!

However, there's nothing like this for public field names. If I want to rename a field of a struct, I have to make it a breaking change, and can't forward old name to the new one.

There's also nothing reliable for renaming `enum` variants. It can be partially hacked with an associated constant, but that works only for fieldless enums, and isn't compatible with wildcard imports.

I won't mention any syntax here to delay this bikeshed, but would the functionality make sense in general?

I assume it'd be mostly a syntax-level thing that replaces one name with another as soon as possible in the compilation pipeline.

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [June 17, 2024, 7:45pm UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/2 "2024-06-17T19:45:39Z")

</div>

For fields, at least, it opens some interesting things around borrow splitting or construction or destructuring. Is `let Foo { a, b } = foo;` legal if they're both actually the same field, for example?

Can you elaborate on the scenario where you have public fields that need renaming? I've always just considered this part of the tradeoff of public fields, assuming people would use a method instead of they want freedom to do things like rename.

---

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [June 17, 2024, 8:40pm UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/3 "2024-06-17T20:40:57Z")

</div>

The `rgb` crate exports `GrayAlpha(T, T)` tuple type, and `.0` and `.1` are not great, and even worse considering that there could be an alpha-first type added that flips meaning of the fields.

I'd like to migrate that to something like `LumaAlpha { l: T, a: T }`, but since the `rgb` crate is used for interoperability between crates, making a new incompatible type has a high cost. If there were field aliases, I could do `pub type GrayAlpha<T> = LumaAlpha<T>` + alias the fields, so that both old `gray.0` code and the new `luma.l` code would continue to work, and keep being interoperable.

* * *

> `let Foo { a, b } = foo;`

I imagine it would be a syntactic find'n'replace early, so it'd parse as `let Foo { alias_of_a: a, alias_of_b: b } = foo;`, and err if the replacement makes it `let Foo { same: a, same: b } = foo;`. Just like `type` alias doesn't create new types, and doesn't change how type-related features work.

---

<div class="post-metadata">

### Author: ![VitWW](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vitww/32/10822_2.png) [@VitWW](https://internals.rust-lang.org/u/VitWW)
#### Post date: [June 17, 2024, 10:30pm UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/4 "2024-06-17T22:30:48Z")

</div>

Syntax could be quite "rust"-like for `struct`:

```rust
struct Point {horizontal: i32, vertical: i32}

type Point.x = Point {horizontal: x, ..}
type Point.y = Point {vertical: y, ..}

```

---

<div class="post-metadata">

### Author: ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)
#### Post date: [June 17, 2024, 11:15pm UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/5 "2024-06-17T23:15:19Z")

</div>

You can hack partial syntax compatibility together by having one type `Deref` to the other via pointer cast. This is how nalgebra enables field access syntax for their vector types despite

Just aliasing on a per-field-identifier basis is much simpler, but the generalized form is a form of safe `union` that allows fields to arbitrarily alias each other.

For destructuring that names a field twice with different names, I'd expect that to be an identical result to if the field gets named twice by the same identifier.

---

<div class="post-metadata">

### Author: ![Valaphee](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/valaphee/32/10755_2.png) [@Valaphee](https://internals.rust-lang.org/u/Valaphee)
#### Post date: [June 20, 2024, 9:05am UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/6 "2024-06-20T09:05:11Z")

</div>

Not exactly related, but similar: providing a better path for migrating. Because theoretically this could be somewhat automated. especially for simple things like renaming.

Kotlins Deprecated annotation ([Deprecated - Kotlin Programming Language](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-deprecated/)) has a ReplaceWith. And theoretically you could write a migrate tool, which just replaces the usage with the new one.

But this requires knowing when the breaking change is happening in an earlier version.

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [September 18, 2024, 9:05am UTC](https://internals.rust-lang.org/t/name-aliases-for-struct-fields-and-enum-variants/21041/7 "2024-09-18T09:05:46Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
