rust-lang / rfcs

RFCs for changes to Rust
https://rust-lang.github.io/rfcs/
Apache License 2.0
5.97k stars 1.57k forks source link

Allow `self` as an identifier in patterns #3684

Open fiveseven-lambda opened 3 months ago

fiveseven-lambda commented 3 months ago

Proposal

Allow the use of self as an identifier in identifier patterns (foo @ Foo { bar, baz }).

Motivation

As seen in the following search results within the rust-lang/rust repository, there are numerous instances where developers want to destructure a struct in a let statement with self on the right-hand side.

Search results in the rust-lang/rust repository

For example, consider the following code in library/std/src/sys/pal/sgx/net.rs:

fn try_into_inner(self) -> Result<FileDesc, Socket> {
    let Socket { inner, local_addr } = self;
    Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr })
}

If self were allowed as an identifier in identifier patterns, this could be written more concisely as:

fn try_into_inner(self @ Socket { inner, local_addr }) -> Result<FileDesc, Socket> {
    Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr })
}

This is not only more concise but also more natural from a language specification standpoint.

fiveseven-lambda commented 3 months ago

But what about &self and &mut self? We can write &self as a shorthand for self: &Self, but it might be confusing if &self @ Foo { bar, baz } was desugared into self @ Foo { bar, baz }: &Self. There are two possible ways:

  1. Allow only self in patterns, and disallow &self and &mut self (so that we have to write as self @ Foo { bar, baz }: &Self)
  2. Let &self @ Foo { bar, baz } and &mut self @ Foo { bar, baz } be shorthands for self @ Foo { bar, baz }: &Self and self @ Foo { bar, baz }: &mut Self, respectively.