# New RFC for delegation: anyone interested in contributing?

**URL:** <https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644>\
**Category:** language design\
**Created:** [January 25, 2018, 9:14am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644 "2018-01-25T09:14:15Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![BatmanAoD](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/batmanaod/32/1512_2.png) [@BatmanAoD](https://internals.rust-lang.org/u/BatmanAoD)\
**Post date:** [April 4, 2018, 7:07pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/41 "2018-04-04T19:07:41Z")

</div>

I’m not sure I understand: since default trait implementations can be provided with custom `#[derive(Trait)]`, what is the advantage of using delegates in that case (`delegate *`) instead of custom-derive?

@elahn Once the above question has been answered I’d be happy to write up something for the “drawbacks” section, or, if I find the answer particularly enlightening, perhaps I shall withdraw my concern entirely! 😃

---

<div class="post-metadata">

**Author:** ![tmccombs](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tmccombs/32/1845_2.png) [@tmccombs](https://internals.rust-lang.org/u/tmccombs)\
**Post date:** [April 4, 2018, 10:53pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/42 "2018-04-04T22:53:10Z")

</div>

> since default trait implementations can be provided with custom #[derive(Trait)], what is the advantage of using delegates in that case (delegate \*) instead of custom-derive?

Two things:

1. You can use "\*" for most methods (and etc.) but then have a custom implementation for one or two methods.
2. It is significantly easier than writing a proc macro for custom-derive

---

<div class="post-metadata">

**Author:** ![tmccombs](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tmccombs/32/1845_2.png) [@tmccombs](https://internals.rust-lang.org/u/tmccombs)\
**Post date:** [April 4, 2018, 11:03pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/43 "2018-04-04T23:03:55Z")

</div>

> [@elahn](#):
>
> could you take a look at this and add more detail if necessary?

lgtm

---

<div class="post-metadata">

**Author:** ![BatmanAoD](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/batmanaod/32/1512_2.png) [@BatmanAoD](https://internals.rust-lang.org/u/BatmanAoD)\
**Post date:** [April 5, 2018, 12:28am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/44 "2018-04-05T00:28:04Z")

</div>

Thanks.

I had another thought: custom derive wouldn’t really handle the case where `struct Foo` has two members, `bar` and `baz`, for which `baz` implements one interesting delegatable-trait but `bar` implements the other.

---

<div class="post-metadata">

**Author:** ![BatmanAoD](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/batmanaod/32/1512_2.png) [@BatmanAoD](https://internals.rust-lang.org/u/BatmanAoD)\
**Post date:** [April 5, 2018, 12:43am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/45 "2018-04-05T00:43:16Z")

</div>

@elahn I’ve added my concern to the “Drawbacks” section. I rescind the third bullet point in my original comment, since it applies equally to manually writing delegation functions.

---

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [April 5, 2018, 2:03am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/46 "2018-04-05T02:03:32Z")

</div>

> [@elahn](#):
>
> Thank you, @Ixrec for writing a lot of this. I’d love any further input you might have if you’ve got time. 🙂

I sorta took a mental break from this discussion since a) I was a pretty heavy contributor last time so it seemed best not to overdo it, b) I haven't had any new, strong opinions since last time, and c) I was never entirely clear on what was missing to get this to the proper RFC stage. I guess it's no surprise I approve of the current draft (which is [Delegation RFC (draft) - HackMD](https://hackmd.io/ZUEHoEgwRF29hbcIyUXIiw) right?) since it appears to be pretty similar to what I wrote, with a ton of new details.

But I can toss around some specific comments:

- Those "delegate blocks" are... whoa. I'm gonna need a lot of convincing that that's not going way too far for a pure sugar feature. Was there a concrete use case where this is a huge win, or is it just the end result of investigating what it would take to make some of the suggested extensions work?
- I like the extension to inherent impls. I'm not really understanding @newpavlov's arguments that this is insufficient for the "inherent traits" use cases.
- I'm tempted to push for `self.field` instead of `field`, since `self.field` seems like it might be forward-compatible with more extensions, as well as forward-compatible with making the `self.` optional in the future, and because `delegate * to 0` for tuple structs is super weird. But this probably depends a lot on how common delegation to non-fields is, so maybe it's not worth further bikeshedding at the RFC stage.
- The last unresolved question of "How does delegation interact with specialization?" seems like it's already answered by the general principle that this is just sugar for an impl you could write manually. Was there a specific reason I missed why saying "it should just work" doesn't cut it?
- I think we've hammered out enough detail in the current draft that further discussion is more likely to over-engineer than anything else. If there is some critically broken or underspecified part of this proposal, I won't have a clue what it is until it's posted as a real RFC and the masters of type-fu point it out to us. And the big, elephantine question we do know about has always been which of the many potential extensions are valuable and which aren't, and we're never going to find out until this is in nightly and people start trying it.

---

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [April 5, 2018, 2:25am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/47 "2018-04-05T02:25:06Z")

</div>

> [@Ixrec](#):
>
> I was never entirely clear on what was missing to get this to the proper RFC stage

I skimmed the old threads, and with the benefit of hindsight this seems a lot less mysterious to me now. I completely forgot that the RFC which got postponed never really incorporated any of the feedback and bore almost no resemblance to the strawmen proposals we were throwing around in the old internals thread. In particular, none of the issues in [Rfc: delegation of implementation by contactomorph · Pull Request #1406 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/pull/1406#issuecomment-317641341) apply to our current draft. Within the old internals thread itself, the only strong concern was [3 weeks to delegation! Please help - #33 by withoutboats](https://internals.rust-lang.org/t/3-weeks-to-delegation-please-help/5742/33) which I believe is a non-issue with our current draft because arbitrary expressions and static methods are now considered potential extensions.

---

<div class="post-metadata">

**Author:** ![elahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elahn/32/1652_2.png) [@elahn](https://internals.rust-lang.org/u/elahn)\
**Post date:** [April 5, 2018, 2:36am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/48 "2018-04-05T02:36:43Z")

</div>

Thanks, @Ixrec. Maybe I got a little paranoid about it stalling or being postponed again. 😃

@Yoric, @kaedroho, @JustAPerson and @pythoneer would you like to edit [Rationale and alternatives](https://hackmd.io/ZUEHoEgwRF29hbcIyUXIiw?view#Rationale-and-alternatives) to make sure your preferences/suggestions/concerns are accurately represented?

I’ll give it until end of day tomorrow for people to do any last minute polishing they’ve got planned, then submit the RFC if there are no objections by then.

Thanks, everyone for your contributions, they’ve been a big help. If we continue this collaborative style throughout the RFC process, I’ve no doubt we can address any concerns that arise and get this puppy accepted!

---

<div class="post-metadata">

**Author:** ![Lisoph](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lisoph/32/3901_2.png) [@Lisoph](https://internals.rust-lang.org/u/Lisoph)\
**Post date:** [April 5, 2018, 7:47am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/49 "2018-04-05T07:47:41Z")

</div>

@elahn or anyone else: Feel free to add my syntax idea to the alternatives. That site doesn’t appear to be working on my machine, I’m unable to add it myself.

---

<div class="post-metadata">

**Author:** ![newpavlov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/newpavlov/32/3290_2.png) [@newpavlov](https://internals.rust-lang.org/u/newpavlov)\
**Post date:** [April 5, 2018, 8:07am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/50 "2018-04-05T08:07:36Z")

</div>

> [@Ixrec](#):
>
> I like the extension to inherent impls. I’m not really understanding @newpavlov’s arguments that this is insufficient for the “inherent traits” use cases.

I am not saying it insufficient. My point is that it has issues (which I've listed) compared to an alternative [approach](https://github.com/rust-lang/rfcs/pull/2375).

---

<div class="post-metadata">

**Author:** ![zrk](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zrk/32/4447_2.png) [@zrk](https://internals.rust-lang.org/u/zrk)\
**Post date:** [April 5, 2018, 10:23pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/51 "2018-04-05T22:23:18Z")

</div>

I’ve been thinking about an alternative design that would rely on a “magic” `Delegate<Trait, Inner=Type>` trait, pretty much like the `Iter` trait is magic in that it allows `for range` syntax.

Basically, to delegate in a struct `Boss` the implementation of a trait `Work` to a member (or a getter) `worker`, you would implement the `Delegate<Trait>` for `Boss`:

```rust
impl Delegate<Work> for Boss {
    type Inner = Worker;
    fn inner(&self) -> &Self::Inner { self.worker }
}

```

Then, the compiler would automatically implement `Work` for `Delegate<Work, Worker>`:

```rust
// This would be generated by the compiler
impl<T: Work, U: Delegate<Work, Inner = T>> Work for U {
    // single fn defined in the Work trait, see gist
    fn do_work(&self) -> u64 {
        self.inner().do_work()
    }
}

```

Here’s some links to a [gist](https://gist.github.com/rust-play/6fb51daf3a62d898769fc9184dc9ecd3) and [playground](https://play.rust-lang.org/?gist=6fb51daf3a62d898769fc9184dc9ecd3&version=stable) showing a more complete implementation (minus the automatic generation by the compiler…).

Here are some pros and cons to this alternative:

- + No need for added syntax, and the “magic” looks pretty minimal, while still allowing the purpose of “delegate blocks” (transforming the `self`/`&self`/`&mut self`/`Self` types).
- + Other functions could accept the std::delegate::Delegate trait, e.g. to perform special treatment on structs that delegate.
- + Naturally prevents from implementing `Delegate<Trait>` twice for the same trait (even with different Inner types).
- + This alternative would naturally extend to inherent impls by implementing a `Delegate` trait (without a type parameter).
- - The syntax boilerplate is still significant (see [gist](https://gist.github.com/rust-play/6fb51daf3a62d898769fc9184dc9ecd3)). This could be reduced with an autoderive for the Delegate trait and/or smart defaults (blanket impls?)? Or we could add syntax sugar on top of the trait?
- - This alternative does not address the possibility for “partial delegation” (e.g., override the implementation of some of the trait’s `fn`, or delegate only some of the trait’s `fn`). Maybe we could by taking the additional functions defined in the impl of the Delegate trait and putting them in the automatically generated impl of the Work trait for Delegate, but this add more compiler magic.

I’m fairly new to rust, and I’ve only been following this discussion for a few days (in particular I have limited knowledge of the previous RFC that was abandoned), so there might be major caveats (orphan rule?) in this alternative design. I may even have missed the point of the delegation RFC. If so, I apologize in advance for the possible lack of quality or relevance of this contribution.

---

<div class="post-metadata">

**Author:** ![Naorume](https://avatars.discourse-cdn.com/v4/letter/n/839c29/32.png) [@Naorume](https://internals.rust-lang.org/u/Naorume)\
**Post date:** [April 6, 2018, 3:35am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/52 "2018-04-06T03:35:19Z")

</div>

About the RFC question:

> Is the word “delegate” really appropriate in this context?

If I am right, it is wanted to select one portion of source code from one origin and insert it in a destination, after modifying/filtering the namings accordingly under the needs, maintaining the origin-destine code relationship.

This way, when the code in the origin is modified (added or retouched methods, fields, etc), those items/code become propagated to all the destinations whom linked such model for replicate, as if it were done by hand, what means is the lexer engine who would play here, before sending to compiler stage.

If this is correct, I think that `propagate` or `replicate` could be alternative words for this matter. Depending of were is going to be placed Origin and Destine in the syntax:

```rust
 // Example.1 , modification of stile proposed in RFC 

 impl Foo for Bar {
     replicate Foo { * | field_des }
 }
 // The redundancy of signalizing Foo as Origin is helpful for newcomers
 // , just it is needed to say it can be omitted.

```

But, reading the comments of the threads talking about this matter, the content of `{...}`, with the cross of time (may be years), it could become a:

```rust
 // Example 2, refactoring matrix

 // What From To
 // ------------ ----------- -----------
 { 
     fn * { fieldA_ori | fieldA_des }
     fn func_name { fieldB_ori | fieldB_des }
     field { fieldC_ori | fieldC_des }
     name fn { func_name_ori | func_name_des }
     type { typeA_name | typeB_name }
     use for { self.0 typeA_name | self.0 typeB_name }

     fn func_name2, fn func_name3
     {
         fieldB_ori | fieldB_des,
         fieldC_ori | fieldC_des,
         fieldD_ori | fieldD_des,
     }
     etc
 }

```

What I think would be very hard to follow, newbies and no so newbies, from my humble point of view. Or probably I did not understood this part of the RFC.

But, thinking on it, one thing the code text editors could do after detect the `delegation` is to show the replicated code/functions in place ( with an unfold button ), for quick understanding of whats being replicated in `example 2`. In fact, If that happens, probably I would not find hard difficulties in the `example 3`, what I would consider in such case almost an advantage, because I would see in real time the pattern changes. Or perhaps is to much dependence or guessing in thirds ?

I am just starting to explore the language, so I apologize in advance for the lack of quality in my comments.

Thank you all for being there fighting

---

<div class="post-metadata">

**Author:** ![elahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elahn/32/1652_2.png) [@elahn](https://internals.rust-lang.org/u/elahn)\
**Post date:** [April 6, 2018, 10:16am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/53 "2018-04-06T10:16:56Z")

</div>

The [RFC has been posted](https://github.com/rust-lang/rfcs/pull/2393).

---

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [April 6, 2018, 3:00pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/54 "2018-04-06T15:00:10Z")

</div>

To be honest, I’m not sure how far it brings us if we only have the ability to delegate associated methods (as opposed to entire impls). To me, it feels like 95% of the time I spend writing delegated impls is spent on getting all of the generic type parameters and where bounds and associated types correct, whereas the methods can usually be copied and pasted between each impl for a trait without any modification beyond a search and replace for the delegated field name.

---

<div class="post-metadata">

**Author:** ![Restioson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/restioson/32/3215_2.png) [@Restioson](https://internals.rust-lang.org/u/Restioson)\
**Post date:** [April 6, 2018, 8:46pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/55 "2018-04-06T20:46:20Z")

</div>

Re: advanced cases, I think that for sufficiently advanced or complex cases one should just write out the function, to an extent. Perhaps complex stuff like delegating to an enum might be better left to using a macro or writing it out yourself manually. That being said, simpler stuff like delegating to an expression (e.g `self.inner.lock()`) or something would be nice to have a syntax for. In regards to that, it would be nice if any expression would be able to be put there (such as a block) to allow arbitrary levels of getting, locking, cloning, atomic loads, or whatever the user needs to do.

---

<div class="post-metadata">

**Author:** ![Restioson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/restioson/32/3215_2.png) [@Restioson](https://internals.rust-lang.org/u/Restioson)\
**Post date:** [April 6, 2018, 8:51pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/56 "2018-04-06T20:51:43Z")

</div>

It might also be worth it to look at how Kotlin does delegation ([https://kotlinlang.org/docs/reference/delegation.html](https://kotlinlang.org/docs/reference/delegation.html)).

---

<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:** [April 7, 2018, 4:34am UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/57 "2018-04-07T04:34:16Z")

</div>

A thought not important enough for the RFC thread: should `delegate fn * to ...` also be supported? (And `const *` and `type *` and…)

---

<div class="post-metadata">

**Author:** ![burakumin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/burakumin/32/1838_2.png) [@burakumin](https://internals.rust-lang.org/u/burakumin)\
**Post date:** [April 9, 2018, 4:32pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/58 "2018-04-09T16:32:17Z")

</div>

@elahn I'm very deceived about how things turned about the subject. When I contacted you months ago you showed no signs of life. I have no issues with that. We all have periods when we have other priorities. That was precisely my case these days but **I had already started a new RFC**. That was the reason I invited interested people to contact me in the [original post](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644).

And when I come back I remark you created an independent RFC within 3 weeks. Now of course the fact I was the author of the original RFC does not give me any ownership on this feature but maybe we could have joined our efforts. I have only skimmed the new RFC but when considering the reason that prevented the original RFC to be accepted I really doubt that this new one has better chance. Maybe my position will change when I have a better view.

> [@Ixrec](#):
>
> I skimmed the old threads, and with the benefit of hindsight this seems a lot less mysterious to me now. I completely forgot that the RFC which got postponed never really incorporated any of the feedback and bore almost no resemblance to the strawmen proposals we were throwing around in the old internals thread. In particular, none of the issues in [Rfc: delegation of implementation by contactomorph · Pull Request #1406 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/pull/1406#issuecomment-317641341) apply to our current draft.

@cramertj's comment was not what blocked the RFC. Look at his [next message](https://github.com/rust-lang/rfcs/pull/1406#issuecomment-317811198). In the end I think he was confident that the RFC could have be accepted with some clarification.

@withoutboats has always been the one opposing the acceptation and as far as I can say what he wanted was:

- a really narrower focus to start with (notably: delegation to fields only)
- a detailed discussion on the validity of delegation depending on the type of `self`.

I still have to read the new RFC with great care but it does not seem to me that any of these conditions are met.

---

<div class="post-metadata">

**Author:** ![elahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elahn/32/1652_2.png) [@elahn](https://internals.rust-lang.org/u/elahn)\
**Post date:** [April 10, 2018, 9:35pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/59 "2018-04-10T21:35:16Z")

</div>

Hey @burakumin, I’m sorry you feel that way. I did try to contact you and looked for an RFC draft to contribute to. Since there appeared to be no activity, I created a [collaborative RFC draft on HackMD](https://hackmd.io/ZUEHoEgwRF29hbcIyUXIiw?view#) which the community has worked on the last few weeks and continues to work on throughout the RFC process; I am only one contributor.

My only interest is in having the best possible initial and forward compatible design that answers all necessary questions for the RFC to be accepted, so we can all reap the benefits of delegation in Rust. I hope you will join forces with us and help make this a reality.

Just because the RFC has been posted, doesn’t mean it’s finalised. Please add to, modify and make it better. It would be great if everyone following the [RFC PR](https://github.com/rust-lang/rfcs/pull/2393) would modify the draft to address suggestions, questions and concerns, with a discussion here when necessary.

---

<div class="post-metadata">

**Author:** ![elahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elahn/32/1652_2.png) [@elahn](https://internals.rust-lang.org/u/elahn)\
**Post date:** [April 19, 2018, 9:41pm UTC](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644/60 "2018-04-19T21:41:03Z")

</div>

Hey all, I’m in a health crash and could really use some help addressing the questions raised in the RFC PR thread. Any volunteers?

[Previous page](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644.md?page=2)

[Next page](https://internals.rust-lang.org/t/new-rfc-for-delegation-anyone-interested-in-contributing/6644.md?page=4)
