# Closures and functional traits

**URL:** <https://internals.rust-lang.org/t/closures-and-functional-traits/23965>\
**Category:** language design\
**Created:** [January 31, 2026, 4:51pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965 "2026-01-31T16:51:31Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [January 31, 2026, 4:51pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/1 "2026-01-31T16:51:31Z")

</div>

# TL;DR:

Assume we have following trait and a function that uses it:

```rust
trait SingleMethodTrait<T> {
    fn do_stuff<'a>(self, &'a T) -> impl Future<Output = ()> + use<'a>;
}

async fn do_bigger_stuff(
    do_stuff: impl SingleMethodTrait<u32>,
) {
    ...
    let inner_param = 42u32;
    do_stuff.do_stuff(&inner_param).await;
    ...
}

```

Then, we should be able to provide that trait's implementation by writing closure:

```rust
do_bigger_stuff(async |i| {
    println!("{i}");
}).await;

```

This should work if trait has exactly one non-static method (with any variation of `self` parameter), all its associated types are referenced in that method's signature (i.e. can be inferred from usage spot), and it's the only non-marker trait in the bound declared.

# Rationale

Allow convenient syntax for implementation of any Fn-like trait, with all variations of method signature available. This should also allow higher-kinded functions, as nothing forbids us from methods like `fn show_it(&self, item: &impl Debug)`. Also removes need to make more stdlib traits for functions.

# Prior art

- [Java Functional Interfaces](https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8), [Oracle Java Tutorial - Lambda Expressions](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
- Initial attempt from 2017 [Closure syntax for non-function traits](https://internals.rust-lang.org/t/closure-syntax-for-non-function-traits/5739)

# Additional possible extensions

- Syntax or macro to declare such functional trait in-place:

```rust
fn do_stuff(
    func: callable! {
        fn call<'a>(self, &'a mut Foo) -> impl Future<Output = ()> + use<'a>;
    }

```

- Marker trait `Callable` which tells compiler that this trait is equivalent to any other marked trait with the same signature of its method

# Details

Recently I hit issue with declaring proper async closure type yet again. It was caused by lifetime bounds propagation from arguments to returned future, but that's not what I'd like to talk about.

What I observe is that we're multiplying number of magic traits each time we hit some new limitation. We started with Fn\* traits to cover passing functions - yet they couldn't resolve linking closure's lifetime to its output. We added AsyncFn\* when we decided to resolve this issue for async functions, for which it was really critical. We're talking about LendingFn\* traits family which should land inbetween those two. And all these traits are magical and have special meaning to compiler.

Yet, certain nontrivial cases with callables' signatures are still not covered. Some may be never covered, and all this is because you can't express whole range of possible method signatures with parametrizing traits, at least it seems so now. Rustaceans often workaround this kind of issue with their custom traits, where all the bounds needed are written explicitly. Unfortunately, providing implementation for such traits is often tedious, since you need to write down all the captured variables and their types, esp. if that closure is used only once.

What I'd like to discuss is the ability to generate trait implementation from a closure for any compatible trait.

---

<div class="post-metadata">

**Author:** ![197g](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/197g/32/7276_2.png) [@197g](https://internals.rust-lang.org/u/197g)\
**Post date:** [January 31, 2026, 7:09pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/2 "2026-01-31T19:09:09Z")

</div>

Prior art should expand on the relation to Java Functional Interfaces, which is very similar to this for a similar use case. Even better it will provide a plethora of additional motivating examples and demonstrate that it has the potential of shifting the design space around it. (That should be discussed as a slight negative, too, for compatibility with previous editions if necessary).

---

<div class="post-metadata">

**Author:** ![ais523](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@ais523](https://internals.rust-lang.org/u/ais523)\
**Post date:** [February 1, 2026, 5:47am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/3 "2026-02-01T05:47:03Z")

</div>

I think something like this might be needed – the basic problem is that there's a sort of "ecosystem split" between `Fn` traits and closures on one side, and non-standard-library traits and manually-implemented closure-equivalents on the other, and it can be hard to convert when you have one but need the other.

One of the ways I get a deeper understanding of Rust is by answering questions about it on Stack Overflow, and at least two people independently had problems in which they needed to provide a generic callback for which the output type depended on the generic parameters. An approximation of what they were aiming for in psuedo-Rust syntax would look like this:

```rust
for<T: Trait1> Fn(T) -> impl Trait2 + use<T>

```

Obviously, this doesn't work in current Rust – although it's obvious what the syntax would mean by analogy with existing language features, it requires at least two hypothetical features (types as higher-ranked trait bounds and `impl Trait` return values from `Fn`) that don't exist and are unlikely to be implemented any time soon.

On the other hand, despite being impossible to write using `Fn` (and there being no real propsects of being able to do so any time soon), you can write this as a custom trait just fine:

```rust
trait MyFn {
    type Output<T: Trait1>: Trait2;
    fn call<T: Trait1>(&self, t: T) -> Self::Output<T>;
}

```

This is the suggestion that I gave to both of those people, but it has the big downside that you can't create closures that implement `MyFn` – you have to simulate the closure manually (by creating a `struct` to hold the captures and implementing `MyFn` on it) rather than being able to use closure syntax.

As such, I'm in favour of implementing something like this. I would note that to avoid creating a new semver hazard, it should probably be restricted to traits that have exactly one required method (but allow any number of provided methods) – adding a provided method to a trait is normally not a semver break, so allowing provided methods to influence whether it was possible to implement the trait with a closure would be needed to preserve that. It would also need to be able to provide generic associated types (as in the example above), but I _think_ you can do that by making them all TAITs in the generated trait implementation (with the trait's required method as the defining use).

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 1, 2026, 9:44am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/4 "2026-02-01T09:44:48Z")

</div>

Thanks for suggestion. Added to OP.

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 1, 2026, 9:48am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/5 "2026-02-01T09:48:44Z")

</div>

That's what I'm talking about. One cannot express all possible function signatures through fixed set of traits. So better generate trait implementation from closure for any compatible trait.

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [February 1, 2026, 4:47pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/6 "2026-02-01T16:47:26Z")

</div>

Based on my personal experience with functional interfaces in Java, and with refactoring in Rust and Java, I recommend that this feature should not be implicitly enabled by having only one method; rather, the trait should opt in with an attribute. This has the following benefits:

- If a trait has one method _now_ but will have more later, it can be ineligible for closure syntax immediately, preventing the need for painful refactoring later. (Yes, adding a method is a breaking change. Not every trait is public in a a library published to [crates.io](http://crates.io); many are private to large projects which can update the definition and usages together.)

- In some cases, writing the method name is important documentation about what the method does, and making it anonymous makes the code less clear. (This may be less of a problem for Rust than Java, because Rust does not have anonymous inline class syntax as the option immediately adjacent to closure syntax, and so there is no opportunity for tools to unwisely recommend closure syntax instead.\[1\])

Both of these points _could_ be addressed by saying "well don't do that then", but I do not think that is wise.

* * *

1. I think it would be useful if Rust did have anonymous inline trait impls too; it would work like a closure but be able to implement a trait with multiple methods. But that's an entire other discussion, with many more syntax questions.

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 2, 2026, 2:18pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/7 "2026-02-02T14:18:10Z")

</div>

IMO trait breakage you described isn't unique to functional interfaces. Any new required method will break all implementations of that trait. This may be partially remedied by allowing any number of provided methods in functional interfaces, though that's a different story. I don't like idea of this feature being opt-in. It will introduce unnecessary limitation for a feature which is essentially a complex syntactic sugar.

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sfackler/32/9_2.png) [@sfackler](https://internals.rust-lang.org/u/sfackler)\
**Post date:** [February 2, 2026, 3:09pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/8 "2026-02-02T15:09:26Z")

</div>

Some historical discussion of a related proposed feature (anonymous struct impls): [https://github.com/rust-lang/rfcs/pull/2604](https://github.com/rust-lang/rfcs/pull/2604)

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [February 2, 2026, 3:41pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/9 "2026-02-02T15:41:14Z")

</div>

> [@target\_san](#):
>
> IMO trait breakage you described isn't unique to functional interfaces. Any new required method will break all implementations of that trait.

Yes, of course. But one is easy and the other is not. Currently, if a new required method is added, the necessary work is to add that method to every implementation — a simple job (other than deciding what the new function should do in each case). But if one of those implementations was using closure syntax, then it must be refactored away from being a closure to being an explicit struct; this may be difficult and irregular.

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 2, 2026, 6:02pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/10 "2026-02-02T18:02:06Z")

</div>

Thank you, I haven't seen that discussion, though I've seen mentions of this approach in the discussion from 2017 I linked.

Do you think full "functional interfaces" RFC has any chances? Unfortunately I'm not quite familiar with current state of affairs in lang team.

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [February 2, 2026, 6:29pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/11 "2026-02-02T18:29:41Z")

</div>

> [@target\_san](#):
>
> I don't like idea of this feature being opt-in. It will introduce unnecessary limitation for a feature which is essentially a complex syntactic sugar.

I skimmed the std's [trait listing](https://doc.rust-lang.org/std/all.html#traits) and I'd say that most single-method traits never make sense to implement as a closure. If it wouldn't make sense to implement a `from_fn()` function for a trait today, making that conversion implicit likely isn't any more sensible!

---

<div class="post-metadata">

**Author:** ![JarredAllen](https://avatars.discourse-cdn.com/v4/letter/j/a183cd/32.png) [@JarredAllen](https://internals.rust-lang.org/u/JarredAllen)\
**Post date:** [February 2, 2026, 6:50pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/12 "2026-02-02T18:50:23Z")

</div>

Defining a closure inline sounds useful, but I'd prefer if it had to be explicit that it's defining a trait implementation instead of just a function. I lean towards reusing `as` casting (though I'm open to other ideas), maybe something like:

```rust
fn takes_iterator<I: Iterator>(iter: I) { .. }
takes_iterator((|| None) as impl Iterator<Item = u32>);

```

Also making it a cast could allow for named functions to be used, like:

```rust
fn returns_none<T>() -> Option<T> { None }
takes_iterator(returns_none::<u32> as impl Iterator<Item = u32>);

```

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 3, 2026, 11:50am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/13 "2026-02-03T11:50:22Z")

</div>

AFAIK traits in stdlib are relatively simple, mostly because stdlib is intended to be small. When you get into field of complex signatures, especially involving async, this quickly becomes a problem.

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 3, 2026, 11:54am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/14 "2026-02-03T11:54:55Z")

</div>

But you don't require such explicit cast in case of normal closures. Neither you do in case of normal type inference. I really don't see any benefit in scattering additional obvious casts everywhere. You also don't need this syntax to use free functions, like you don't need to do so with normal `Fn*` traits.

---

<div class="post-metadata">

**Author:** ![idanarye](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/idanarye/32/3346_2.png) [@idanarye](https://internals.rust-lang.org/u/idanarye)\
**Post date:** [February 4, 2026, 1:11am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/15 "2026-02-04T01:11:39Z")

</div>

I'd really rather if instead of doing this for single-method traits, we'd have some syntax that allows implementing a trait as a closure with any number of methods by naming the methods. Something like (bikeshed syntax):

```rust
do_bigger_stuff(impl {
    do_stuff: async |i| {
        println!("{i}");
    },
}).await;

```

---

<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:** [February 4, 2026, 1:39am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/16 "2026-02-04T01:39:26Z")

</div>

> [@idanarye](#):
>
> by naming the methods

That's fun. Like [from\_fn in std::iter - Rust](https://doc.rust-lang.org/std/iter/fn.from_fn.html) for everything 🙂

---

<div class="post-metadata">

**Author:** ![zirconium-n](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zirconium-n/32/9078_2.png) [@zirconium-n](https://internals.rust-lang.org/u/zirconium-n)\
**Post date:** [February 4, 2026, 3:54am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/17 "2026-02-04T03:54:03Z")

</div>

This is somewhat similiar to [Anonymous Classes in Java](https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html). And I think this is definitely useful.

---

<div class="post-metadata">

**Author:** ![gdennie](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gdennie/32/8328_2.png) [@gdennie](https://internals.rust-lang.org/u/gdennie)\
**Post date:** [February 4, 2026, 6:17pm UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/18 "2026-02-04T18:17:02Z")

</div>

Don’t the closure traits, such as `Fn`, already exist to express the acceptance of closures and function pointers?

Isn't this an issue addressable with macros.

Anyway, if ergonomics is the goal, a Haskell-like lightweight syntax similar to how F# maintains two distinct syntactic styles seems like a better path. That said, I’ve grown tolerant of Rust’s ceremony and punctuation noise.

---

<div class="post-metadata">

**Author:** ![target\_san](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/target_san/32/4164_2.png) [@target\_san](https://internals.rust-lang.org/u/target_san)\
**Post date:** [February 5, 2026, 7:21am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/19 "2026-02-05T07:21:15Z")

</div>

Those traits cover only quite limited range of possible signatures. One step outside and you need custom trait, with full-blown manual implementation.

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [February 5, 2026, 7:23am UTC](https://internals.rust-lang.org/t/closures-and-functional-traits/23965/20 "2026-02-05T07:23:52Z")

</div>

The `Fn*` family of traits does not express everything that can be expressed with a trait with one method. For example, you can define a trait with a generic method:

```rust
trait Foo {
    fn foo<T>(&mut self, things: &mut [T]);
}

```

It’s impossible to express this as a usage of `FnMut` or to implement this using a `from_fn()`-style adapter.

[Next page](https://internals.rust-lang.org/t/closures-and-functional-traits/23965.md?page=2)
