# \[Pre? RFC\] Partial types and partial mutability

**URL:** <https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760>\
**Category:** language design\
**Created:** [April 28, 2023, 11:52pm UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760 "2023-04-28T23:52:11Z")\
**Posts on this page:** 10\
**Page:** 2

<div class="post-metadata">

**Author:** ![synek317](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/synek317/32/3371_2.png) [@synek317](https://internals.rust-lang.org/u/synek317)\
**Post date:** [May 4, 2023, 6:38am UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/21 "2023-05-04T06:38:22Z")

</div>

I must admit that initially, I wasn't very convinced by this thread but after reading the discussion, I quite like the proposal.

@VitWW I think you should gather all the comments and ideas and put them into a well-organized document. Here, it is more of a brain-storming session rather than a RFC. It _feels_ very chaotic, which, I believe, can turn off a lot of people.

---

<div class="post-metadata">

**Author:** ![parasyte](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/parasyte/32/8925_2.png) [@parasyte](https://internals.rust-lang.org/u/parasyte)\
**Post date:** [May 4, 2023, 7:49am UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/22 "2023-05-04T07:49:28Z")

</div>

> [@VitWW](#):
>
> My proposal is better _in syntax_ and here is why: it covers all permutation variants

The syntax is also unlike anything in the language. Bikeshedding, I would prefer enum variant types with the existing pattern syntax (or something like it).

```rust
enum E4 {A (i32), B(i32), C (i32), D(i32)}

fn do_ac(e: E4::A | E4::C) { /* .. */ }

```

As for partial borrows, I think the primary reason it hasn't already been addressed is because existing workarounds are sufficient (once you know about them \[1\]). So there isn't much incentive to extend the language.

* * *

1. IMHO, the discoverability of these workarounds is quite poor, and causes the same kinds of questions to appear on URLO and SO. I don't know if that's enough to warrant an entire alien syntax, though. It doesn't feel like it. Worst case, the same amount of questions will continue to appear, but the answers will change from "use this workaround" to "use this language feature".

---

<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:** [May 4, 2023, 10:43pm UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/23 "2023-05-04T22:43:41Z")

</div>

Thanks for feedback!

> [@parasyte](#):
>
> The syntax is also unlike anything in the language.

Ok, lets make partiality looks more Rust-friendly:

1. For Structs and Enum Types partiality is written `::{ /*fields */ }` as "`use`" declaration

```rust
enum E4 {A (i32), B(i32), C (i32), D(i32)}
// for Enums
fn do_eac(e: E4::{A, C}) { /* .. */ } 

struct S4 {a : i32, b : i32, c : i32, d : i32}
// for Structs
fn do_sac(s: S4::{a, c}) { /* .. */ } 

```

1. For Tuple Types use `%lock`( or `lock`) before field instead of unified syntax:

```rust
fn do_t23(t: (lock i32, lock &u32, f64, &f32)) { /* .. */ } 
// same as
fn do_t23(t: (i32, &u32, f64, &f32)::{2,3}) { /* .. */ } 

```

1. For Partial Expression for Struct and Tuples use `.{ /* fields*/ }` syntax, which is similar with "get 1 field" `s.x` and Struct declaration "`{}`":

```rust
let ref_sxy = & s.{x, y};
// same as 
let ref_sxy : & S4::{x, y} = & s.{x, y};

```

1. All not fully filed initialization for Structs are Partly Typed:

```rust
struct S4 {a : i32, b : i32, c : i32, d : i32}

let sac = S4{a : 5, c : 7}; 
    // sac : S4::{a, c}

```

1. For Tuple Types initialization we could use `%lock`( or `lock`) before field instead of unified syntax:

```rust
let t23 = ( lock 2i32, lock & 8u32, 6.0f64, 7.0f32); 
    // t23 : (lock i32, lock &u32, f64, f32)
    // same as
    // t23 : (i32, &u32, f64, f32)::{2, 3}

```

1. For partial mutability we also use `.{ /* fields*/ }` syntax:

```rust
let mut.{a} s = S4{a: 5, b: 7};
let refmut_sa = &mut.{a} s;

```

Is this look better now?

---

<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:** [May 4, 2023, 10:47pm UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/24 "2023-05-04T22:47:19Z")

</div>

> [@synek317](#):
>
> I must admit that initially, I wasn't very convinced by this thread but after reading the discussion, I quite like the proposal.

Thank you for support and understanding!

> [@synek317](#):
>
> I think you should gather all the comments and ideas and put them into a well-organized document. Here, it is more of a brain-storming session rather than a RFC.

That is my goal.

---

<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:** [May 4, 2023, 11:40pm UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/25 "2023-05-04T23:40:26Z")

</div>

> [@parasyte](#):
>
> As for partial borrows, I think the primary reason it hasn't already been addressed is because existing workarounds are sufficient (once you know about them).

From my point of view, main reason is not a minor change is needed for that.

And this Proposal is not only "how to add syntax", but it is also a road-map "how to implement into the language".

> [@SkiFire13](#):
>
> > [@VitWW](#):
> >
> > The only one change to borrow checker: is to borrow whole variable, but it pretends that it borrow permitted fields (and permitted mutability) only of this variable.
> 
> This may be surprisingly difficult to implement properly though.

I've looked into the Rust source, and I agree, I was focused on Type changes, not to borrow changes needed for that. We need to add "Proxy Borrowing":

```rust
struct S4 {a : i32, b : i32, c : i32, d : i32}
let s = S4 {a : 5, b: 6, c: 7, d: 8};
    // s : S4

let r_sd = & s.{d};
    // r_sd : & S4::%{d}
    //
    // r_sd ~ Link(s);
    // borrow-checker borrows ProxyLink(s.d)

let mut mr_sabc = &mut s.{a, b, c};
    // mr_sabc : &mut S4::%{a, b, c}
    //
    // mr_sabc ~ mut Link(s);
    // borrow-checker: mut ProxyLink(s.a), mut ProxyLink(s.b), mut ProxyLink(s.c)

let rr_sbc = & mr_sabc.{b, c};
    // rr_sbc : && S4::%{b, c}
    //
    // rr_sbc ~ Link(mr_sabc);
    // borrow-checker: ProxyLink(ProxyLink(s.b)), ProxyLink(ProxyLink(s.c))

let mut mrr_sa = &mut mr_sabc.{a};
    // mrr_sa : &&mut S4::%{a}
    //
    // mrr_sa ~ mut Link(mr_sabc);
    // borrow-checker: mut ProxyLink(ProxyLink(s.a))

```

When we write a code for partial borrow, the link of object itself returns, but borrow-checker, borrows proxy of permitted fields only.

When we write a code for full (or partial) borrow of a partial borrowed reference, the link of object itself returns again, but borrow-checker, borrows proxy of proxy of permitted fields only.

This new mechanism of Proxy Borrowing is simple and universal.

---

<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:** [May 12, 2023, 4:01am UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/26 "2023-05-12T04:01:03Z")

</div>

I used this discussion to create new Pre-Proposal:

[Partial Types (v3)](https://github.com/VitWW/rfcs/blob/partial_types3/text/0000-partial_types.md)

It is still missing _Reference-level explanation_.

Feedback is welcome!

---

<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:** [May 15, 2023, 3:51am UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/27 "2023-05-15T03:51:07Z")

</div>

I add "Reference-level explanation" to the proposal **Partial Types (v3)** and make it even more simpler!

Do you have any advise or question?

---

<div class="post-metadata">

**Author:** ![Noratrieb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/noratrieb/32/12440_2.png) [@Noratrieb](https://internals.rust-lang.org/u/Noratrieb)\
**Post date:** [May 18, 2023, 8:25am UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/28 "2023-05-18T08:25:14Z")

</div>

This is ambiguous with closures. [Closure with a typed function argument and top level struct constructor break in nightly · Issue #107461 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/107461) happened when rustc added even a subset of it for diagnostics.

---

<div class="post-metadata">

**Author:** ![parasyte](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/parasyte/32/8925_2.png) [@parasyte](https://internals.rust-lang.org/u/parasyte)\
**Post date:** [May 18, 2023, 4:01pm UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/29 "2023-05-18T16:01:46Z")

</div>

That's too bad! Maybe there's an unambiguous alternative that doesn't stray too much from existing pattern syntax in argument position.

---

<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:** [August 16, 2023, 4:02pm UTC](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760/30 "2023-08-16T16:02:46Z")

</div>

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

[Previous page](https://internals.rust-lang.org/t/pre-rfc-partial-types-and-partial-mutability/18760.md?page=1)
