# pre-RFC: delegation by import

**URL:** <https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066>\
**Category:** language design\
**Created:** [October 7, 2019, 3:49pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066 "2019-10-07T15:49:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [October 7, 2019, 3:49pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/1 "2019-10-07T15:49:12Z")

</div>

So recently I posted this idea on Twitter:

> <https://twitter.com/llogiq/status/1180734709267079171?s=19>

The positive feedback makes me think it _may_ be a good idea:

- For structs only (at least for an initial impl)
- `use self.foo::bar` 'imports' the `bar` method of `self.foo` by generating the following function: `fn bar(&self, x: bool, other: Args) -> ReturnValue { self.foo.bar(x, other) }`. The `self` borrowing mode will be that of the original method, as will be the rest of the signature.
- Visibility works as usual; `pub use` to publicly delegate.
- If the `bar` method already exists, it will of course be the same error as if the method had been written twice.
- `Self` types in the original methods will of course keep being made explicit before delegating.
- The private-in-public lint will probably need to be updated.

Would this be worth a try?

---

<div class="post-metadata">

**Author:** ![gbutler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gbutler/32/3670_2.png) [@gbutler](https://internals.rust-lang.org/u/gbutler)\
**Post date:** [October 7, 2019, 4:07pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/2 "2019-10-07T16:07:46Z")

</div>

I'd see an improvement to the delegation story in Rust as a HUGE win. This seems like a reasonable approach that would make delegation much more declarative.

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [October 7, 2019, 4:16pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/3 "2019-10-07T16:16:48Z")

</div>

Will this import attributes on the delegated method as well (e.g. `#[doc]` and `#[inline]` being two very relevant ones I can think of).

---

<div class="post-metadata">

**Author:** ![felix.s](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/felix.s/32/8073_2.png) [@felix.s](https://internals.rust-lang.org/u/felix.s)\
**Post date:** [October 7, 2019, 4:21pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/4 "2019-10-07T16:21:39Z")

</div>

The syntax seems a bit cryptic, though that alone is not a show-stopper to me. More discouraging is the fact that it doesn't seem to be easily extensible to enums (let's forget for a moment that the enum case is currently impossible to type-check anyway, because we still don't have `enum impl Trait`).

I guess one could do this:

```rust
use (match self {
    Foo(x, y) => x,
    Bar(x, y) => y,
})::{foo, bar};

```

but it looks quite ugly.

If we're reusing existing keywords for delegation, how about this instead?

```rust
for {a, b, c} use self.x;

for {foo, bar} use match self {
    Foo(x, y) => x,
    Bar(x, y) => y,    
};

```

It reads almost like English, and doesn't seem to conflict with any grammar production valid inside an `impl` block.

---

<div class="post-metadata">

**Author:** ![jugglerchris](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jugglerchris/32/2661_2.png) [@jugglerchris](https://internals.rust-lang.org/u/jugglerchris)\
**Post date:** [October 7, 2019, 4:22pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/5 "2019-10-07T16:22:40Z")

</div>

I like this idea. It would be really good for newtype wrappers.

Would you include nested uses or just one level? `use self.foo.bar.baz::foo`?

How about in trait implementations? I could see some corner cases - for example:

```rust
struct Foo(Bar);
impl Iterator for Foo {
    type Item = <Bar as Iterator>::Item; // Or use self.0::Item ?
    use self.0::next; // what about `Iterator::count()` etc. - do they get the delegated type's implementation or the trait's provided version?
}

```

---

<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:** [October 7, 2019, 4:33pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/6 "2019-10-07T16:33:18Z")

</div>

I _believe_ that this exact syntax has been suggested before, though I'm at this moment unable to find a reference to where it was.

Personally, with an answer to how documentation is handled (probably allow `#[doc(inline)]` and behave like other re-exports?) and a "Future Possibilities" for how it can be extended to `enum`s (or why it shouldn't be?) this is probably the best option for syntax of a "minimal delegation" first step RFC.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [October 7, 2019, 5:53pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/7 "2019-10-07T17:53:05Z")

</div>

I think it should, at least for `doc`, `inline`, `must_use` and lint settings.

Edit: thinking a bit more about it, we should at least `inline` the delegator methods, and update to `inline(always)` if the delegatee has it.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [October 7, 2019, 5:56pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/8 "2019-10-07T17:56:46Z")

</div>

If we also allow to import from zero-arg methods, it could be made to work with enums and even traits, e.g. if we have a method `inner(&self) -> &Inner` we could `use self.inner.inner_method;`.

I'd leave out more complex variants because they'd easily get unwieldy.

---

<div class="post-metadata">

**Author:** ![bluss](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluss/32/2264_2.png) [@bluss](https://internals.rust-lang.org/u/bluss)\
**Post date:** [October 7, 2019, 7:55pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/9 "2019-10-07T19:55:07Z")

</div>

Sounds very useful but I don't see the connection with `use`. I think it has to be inside an impl block, so you have the right type parameters and bounds as context for the methods, too. Maybe it could use an attribute somehow?

Let's try a completely different syntax for fun.

```rust
struct Foo<T> {
    field1: T,
    field2: Bar,
}

impl<T> Foo<T> where T: Clone {
    /* New syntax */
    delegate fn frob = field2::frob;

    /* is equivalent to */
    fn frob(&mut self, x: i32) -> i32 {
        self.field2.frob(x)
    }
}

impl Bar {
    fn frob(&mut self, x: i32) -> i32 { unimplemented!() }
}

```

---

<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:** [October 7, 2019, 8:33pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/10 "2019-10-07T20:33:27Z")

</div>

> [@bluss](#):
>
> `delegate fn frob = field2::frob;`

My recollection is that the last [conversation about this](https://github.com/rust-lang/rfcs/pull/2393) was leaning towards

```rust
impl<T> Foo<T> where T: Clone {
    delegate frob to self.field2;
}

```

I think the reason for not using `use` was that one might potentially want to allow things like `use MyEnum::*;` inside an impl for its normal use, and thus it shouldn't get co-opted for delegation.

---

<div class="post-metadata">

**Author:** ![bugaevc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bugaevc/32/13651_2.png) [@bugaevc](https://internals.rust-lang.org/u/bugaevc)\
**Post date:** [October 8, 2019, 9:32am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/11 "2019-10-08T09:32:30Z")

</div>

How about

```rust
use self.foo for fn bar;

```

---

<div class="post-metadata">

**Author:** ![Cazadorro](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cazadorro/32/4551_2.png) [@Cazadorro](https://internals.rust-lang.org/u/Cazadorro)\
**Post date:** [October 8, 2019, 2:14pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/12 "2019-10-08T14:14:38Z")

</div>

to clarify, `pub use self.x::{a, b c}` means that I can take struct `Foo` and have instance `foo` and say `foo.a(); foo.b(); foo.c();` and these will delegate to field `foo.x.a(); foo.x.b(); foo.x.c()`? Is there a particular reason why macros couldn't accomplish the same thing?

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [October 8, 2019, 3:18pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/13 "2019-10-08T15:18:58Z")

</div>

Because they don't have access to function signatures, and supplying signatures would defeat the purpose of delegation.

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [October 8, 2019, 7:16pm UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/14 "2019-10-08T19:16:44Z")

</div>

The connection with `use` is that it can be thought of creating an alias, or 'importing' something at an alternative location. So just like in Java where you can reference both static (`SomeClass::someMethod`) and instance (`someObject::someMethod` or even `this::someMethod`) to be used in functional position, `use` could also be, if you forgive the pun, _dual-use_.

The difference would be to allow `.` as joiner after `use`, and it would require the left hand side to be `self` or an index, field or function (with no additional argument but `self`, `&self`, `&mut self`, `Pin<self>` or any other valid receiver) of it.

This way, the syntax is non-ambiguous (because for now `.` is not allowed), and I think we can craft good error messages in case someone writes `use my_module.MyType` by mistake.

---

<div class="post-metadata">

**Author:** ![CreepySkeleton](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/creepyskeleton/32/6079_2.png) [@CreepySkeleton](https://internals.rust-lang.org/u/CreepySkeleton)\
**Post date:** [October 9, 2019, 12:25am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/15 "2019-10-09T00:25:04Z")

</div>

I would suggest `pull frob for self.field2` instead of `delegate`. The latter is quite a long keyword and rust is famous for its keywords shortcuts 😄

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [October 9, 2019, 3:52am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/16 "2019-10-09T03:52:45Z")

</div>

To be clear, the thing being discussed here is instead of writing this:

```rust
struct Foo {
  bar: Bar,
}

impl Foo {
    fn do_stuff(&self) {
        self.bar.do_stuff();
    }
}

```

You would instead write:

```rust
struct Foo {
  bar: Bar,
}

impl Foo {
    use self.bar::do_stuff; // Replace with your favorite alternative syntax.
}

```

Right?

This seems like a super tiny paper cut. One hardly worth modifying Rust for. Even if the signature of `do_stuff` is more complicated I still don't think this is a big enough problem to add more syntax baggage to Rust, and this isn't something I'd want to blow the language strangeness budget on.

---

<div class="post-metadata">

**Author:** ![felix.s](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/felix.s/32/8073_2.png) [@felix.s](https://internals.rust-lang.org/u/felix.s)\
**Post date:** [October 9, 2019, 4:04am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/17 "2019-10-09T04:04:26Z")

</div>

> [@bugaevc](#):
>
> ```rust
> use self.foo for fn bar;
> 
> ```

If normal `use` clauses are to ever be allowed inside `impl` blocks as @scottmcm suggested, this (and the OP's proposal) may conflict with the goal of having a backtracking-free parser for Rust. My own proposal to put `for` first doesn't have this drawback.

> [@mjbshaw](#):
>
> This seems like a super tiny paper cut. One hardly worth modifying Rust for. Even if the signature of `do_stuff` is more complicated I still don't think this is a big enough problem to add more syntax baggage to Rust, and this isn't something I'd want to blow the language strangeness budget on.

When you only delegate a single method with a known signature, it may seem not worth it, but when it's used with a whole trait or even multiple ones, it really starts paying off. This has been a somewhat oft-requested feature that would enable the sorts of patterns that in other OOP languages are usually implemented via inheritance.

---

<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:** [October 9, 2019, 4:56am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/18 "2019-10-09T04:56:24Z")

</div>

> [@mjbshaw](#):
>
> This seems like a super tiny paper cut.

Just as a counterexample, consider forwarding [`serde::de::Visitor`](https://docs.serde.rs/serde/de/trait.Visitor.html). With this adjustment it's (without the `'de`-dependent methods because lifetime complexity)

```rust
impl<'de> Visitor<'de> for MyType {
    use self.raw::{
        expecting,
        visit_bool,
        visit_i8,
        visit_i16,
        visit_i32,
        visit_i64,
        visit_u8,
        visit_u16,
        visit_u32,
        visit_u64,
        visit_f32,
        visit_f64,
        visit_char,
        visit_str,
        visit_string,
        visit_bytes,
        visit_byte_buf,
        visit_none,
        visit_some,
        visit_unit,
        visit_newtype_struct,
        visit_seq,
        visit_map,
        visit_enum,
    };
    serde_if_integer128!(use self.raw::{visit_u128, visit_i128});
}

```

I really don't want to write out the explicit version on my phone; it's a _lot_ more boilerplate to read, even if your IDE can generate it for you.

For a more reasonable example, consider forwarding all the [`Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) methods for your `IntoIter` wrapper type.

The real advantage comes from forwarding a large trait, but it adds clarity to the single case as well as the large one. I think it's a clear positive in some form at least.

> [@felix.s](#):
>
> conflict with the goal of having a backtracking-free parser for Rust

The syntax of allowing `.` in a path (`use self.member::{func}`) doesn't require backtracking (or equivalently, infinite lookahead). It's even LL(3) in the simple case (`use`, `self`, `.`; the `.` means it's a delegation `use`). Even in worst case "you don't know what kind of use tree it is until after you parse the main tree", it doesn't require backtracking/infinite lookahead; you just delay the decision. Parse the use tree and _then_ decide what kind of use treee it is. Backtracking is a problem when you need to reinterpret how you've parsed what you've already passed. If it parses the same on all paths, just delay the decision.

---

<div class="post-metadata">

**Author:** ![programmerjake](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/programmerjake/32/5893_2.png) [@programmerjake](https://internals.rust-lang.org/u/programmerjake)\
**Post date:** [October 14, 2019, 1:55am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/19 "2019-10-14T01:55:54Z")

</div>

It seems obvious to extend this to work on a whole trait:

```rust
struct MyIter<'a, T>(std::slice::Iter<'a, T>);

impl<T> Iterator for MyIter<'_, T>
where
    T: Sync,
use self.0;

```

equivalent to:

```rust
struct MyIter<'a, T>(std::slice::Iter<'a, T>);

impl<'a, T> Iterator for MyIter<'a, T>
where
    T: Sync,
{
    type Item = &'a T;
    #[inline]
    fn next(&mut self) -> Option<&'a T> {
        self.0.next()
    }
    // delegates all the other Iterator members too...
}

```

---

<div class="post-metadata">

**Author:** ![tkaitchuck](https://avatars.discourse-cdn.com/v4/letter/t/eb8c5e/32.png) [@tkaitchuck](https://internals.rust-lang.org/u/tkaitchuck)\
**Post date:** [October 14, 2019, 6:34am UTC](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066/20 "2019-10-14T06:34:43Z")

</div>

If there were an API for a procedural macro to pull in the text of a given import path, then this could be implemented as a macro without adding any special builtin syntax.

[Next page](https://internals.rust-lang.org/t/pre-rfc-delegation-by-import/11066.md?page=2)
