# Top-level self functions \`fn f(self: T)\`

**URL:** <https://internals.rust-lang.org/t/top-level-self-functions-fn-f-self-t/23620>\
**Category:** language design\
**Created:** [October 13, 2025, 6:06pm UTC](https://internals.rust-lang.org/t/top-level-self-functions-fn-f-self-t/23620 "2025-10-13T18:06:35Z")\
**Posts on this page:** 1\
**Showing post:** 21

<div class="post-metadata">

**Author:** ![Ratatouille](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Ratatouille](https://internals.rust-lang.org/u/Ratatouille)\
**Post date:** [March 17, 2026, 11:52am UTC](https://internals.rust-lang.org/t/top-level-self-functions-fn-f-self-t/23620/21 "2026-03-17T11:52:10Z")

</div>

Coincidentally, both this and the sister thread [Testing the waters: UMCS (Unified Method Call Syntax)](https://internals.rust-lang.org/t/testing-the-waters-umcs-unified-method-call-syntax/24014) attempt to solve essentially the same problem, and both were originally (as far as I know) suggested in CAD97's [Weird syntax idea(s) for UMCS](https://internals.rust-lang.org/t/weird-syntax-idea-s-for-umcs/19200).

Since both approaches have their disadvantages — e.g., the `x.(func)(params)` syntax seems hard to swallow for some — to float another alternative: just adding multi-argument `pipe` (and `tap`?) to `std`. This has several major disadvantages, one of which being that you lose two-phase borrowing, the upside being that no new syntax is needed. As a prior: the single-argument [`tap`](https://crates.io/crates/tap) crate is one of the most popular crates in terms of both all-time and recent downloads.

Why not have multi-argument pipe as a crate? You can — see [`pipei`](https://crates.io/crates/pipei) — but it requires nightly (`impl_trait_in_assoc_type`).

---

_[View the full topic](https://internals.rust-lang.org/t/top-level-self-functions-fn-f-self-t/23620)._
