# Pre-RFC: Anonymous Trait Impls

**URL:** <https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648>\
**Category:** language design\
**Created:** [September 30, 2026, 1:26pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648 "2026-09-30T13:26:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![RealRTTV](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/realrttv/32/14592_2.png) [@RealRTTV](https://internals.rust-lang.org/u/RealRTTV)\
**Post date:** [September 30, 2026, 1:26pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/1 "2026-09-30T13:26:25Z")

</div>

Hey there, I was just talking briefly in the Rust discord about ideas for an anonymous trait impl concept, here's what we have so far.

Sample syntaxes actively in-debate:

```rs
fn create_trait(id: u32) -> impl Trait {
    return impl trait { .. }
    return impl trait Trait { .. } // optional type hint
    return move impl { .. }
    return move impl trait { .. }
    return struct impl Trait { .. }
    return struct impl { .. }
}

```

`impl Trait` creates ambiguity about whether it is an expression or an item.

It'd work pretty similarly to closures capturing variables, ex:

```rs
let x = 1;
// create the closure
let my_closure = move || { println!("{}", x); };
// call the closure
my_closure();

```

equivalent to:

```rs
struct Anonymous {
    x: i32,
}
impl Anonymous {
    fn call_the_thing(&self) {
        println!("{}", self.x);
    }
}

let x = 1;
// create the closure
let my_closure = Anonymous { x: x };
// call the closure
my_closure.call_the_thing();

```

So far we've discussed:

1. Instantiation Syntax  
`let x = impl Trait { ... };`  
No `let x = impl Trait for struct { var1, var2 } { ... };` or anything similar. This anonymous impl Trait syntax is meant to be a shorter & simpler version of a regular trait impl with reduced complexity. If any further complexity is needed the user can always just convert it into a conventional item with trait impl.
2. How to create `Self`  
As the field specifics are left unspecified to the compiler, there wouldn't be a way to construct `Self { ... }` within the anonymous trait impl. I am aware that this is a restriction; however I'd like to highlight that 1. Closures cannot be constructed in the body of themselves. 2. If you **need** to construct the anonymous trait impl; you can always make a wrapper function to instantiate the anonymous trait, ex:

```rs
fn create_trait(id: u32) -> impl Trait {
    let x = impl Trait {
        fn id(&self) -> u32 { id }
        fn recreate(&self) -> Self { create_trait(id) }
    };
    x
}

fn do_something(user: User) {
   let x = create_trait(user.id);
}

```

1. Multiple Trait Bounds (`impl Trait1 + impl Trait2`)

```rs
fn foo() -> impl Trait1 + Trait2 {
    return impl { // Is this Trait1 or Trait2?
    }
}

```

Our decision here is to restrict these to be unrepresentable with anonymous traits. Additionally, traits such as `Subtrait: Trait1 + Trait2` couldn't be implemented anonymously due to missing supertraits.

I am very aware that my markdown isn't fancy-looking or anything and I haven't structured this professionally, I can always edit this as we get more refined on what is actually needed and how we'd structure this for an RFC. (Luckily this is a RFC on a RFC lol)

---

<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:** [September 30, 2026, 2:07pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/2 "2026-09-30T14:07:01Z")

</div>

Some prior related discussions:

> [@Closure syntax for non-function traits](https://internals.rust-lang.org/t/closure-syntax-for-non-function-traits/5739):
>
> As impl Trait is getting closer to stabilization, I have been wondering about some syntactic sugaring. Perhaps this has been discussed before. If so, please let me know where. Current state On current nightly with #[feature(conservative\_impl\_trait)] enabled, if I want to write a function that returns an unboxed closure, I can do this: fn add\_number(a: i32) -\> impl Fn(i32) -\> i32 { move |b| a + b } This is nice, I can provide an implementation without going through all the trouble of (1) d…

> [@Idea: Anonymous \`impl\` types that support capturing like closures](https://internals.rust-lang.org/t/idea-anonymous-impl-types-that-support-capturing-like-closures/16314):
>
> I'm using the listener patterns heavily, and I hope there are anonymous impl types that support capturing like closures. When people are defining a listener, they have to define a struct and implement the trait for it. But since the type is used only once. using anonymous impl type can reduce the code to write and make it clearer. I know that it is a bad idea to use anonymous types in library code. But anonymous types (including closures) can help the client codes or test codes easier to write. …

> [@Closures and functional traits](https://internals.rust-lang.org/t/closures-and-functional-traits/23965):
>
> TL;DR: Assume we have following trait and a function that uses it: 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: do\_bigger\_stuff(async |i| { println!("{i}"); }).await; This should work if …

---

<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:** [September 30, 2026, 4:39pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/3 "2026-09-30T16:39:23Z")

</div>

Since Rust is principled about type inference stopping at function boundaries, and the anonymous trait is created _inside_ said boundaries, I say we crank type inference up to the max:

```rust
fn create_trait(id: u32) -> impl Trait {
    move impl {
        fn id() { id }
        fn recreate(new_id) { create_trait(new_id) }
    }
}

```

- `impl` instead of `impl Trait` because we can infer it from the return type. This means that we no longer need to bind it to a variable before returning it.
- No type annotations for the trait methods' arguments and return types. These are determined by the trait definition - no need to repeat them.
- No `self`. There is no "self" access, because the data is obtained closure-style. `self` is for accessing the "parent" value (like `self` inside a closure)
- `move` is needed for the same reasons it's needed in closures.

If we are uncomfortable with having `fn`s without all the annotations, we can also use struct-like syntax:

```rust
fn create_trait(id: u32) -> impl Trait {
    move impl {
        id: || { id },
        recreate: |new_id| { create_trait(new_id) },
    }
}

```

Where the main difference from a struct is that the closures share access to the data.

---

<div class="post-metadata">

**Author:** ![RealRTTV](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/realrttv/32/14592_2.png) [@RealRTTV](https://internals.rust-lang.org/u/RealRTTV)\
**Post date:** [September 30, 2026, 6:15pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/4 "2026-09-30T18:15:31Z")

</div>

I'm a big fan of a lot of this. `move impl` seems much better. However I'm concerned with it being read as an `impl` and not `impl trait`. `impl` blocks exist on types, and with looking at the body only, it's not obvious to infer that `move impl` means `impl Trait`.

IMO I'd prefer `move impl trait` to fix this, however it is three keywords in a row and I'm also not a huge fan of that.

I think we need to cover `self` as a valid parameter. Interop with existing code and using anonymous trait impls becomes difficult if they supply a &self vs a &mut self parameter; or none at all. What we are allowed to do with this type and it's captures becomes different depending on the &self and &mut self parameter.

+ on the `move` tho.

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [October 1, 2026, 12:43am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/5 "2026-10-01T00:43:18Z")

</div>

I have some corner cases to consider:

```rust
fn foo() -> impl Trait1 + Trait2 {
    return impl { // Is this Trait1 or Trait2?
    }
}

```

If `impl A + B` is not allowed for non-trivial `B`, then `trait C: A + B` and use `impl C` instead.

---

<div class="post-metadata">

**Author:** ![theemathas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/theemathas/32/11817_2.png) [@theemathas](https://internals.rust-lang.org/u/theemathas)\
**Post date:** [October 1, 2026, 4:18am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/6 "2026-10-01T04:18:48Z")

</div>

My preferred syntax is `struct impl TraitName { .... }`. This avoids any syntactic ambiguity since the token sequence `struct impl` is currently not in the language. And I think that someone who hasn't seen this syntax before is more likely to understand the meaning of this syntax than with other syntaxes.

---

<div class="post-metadata">

**Author:** ![theemathas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/theemathas/32/11817_2.png) [@theemathas](https://internals.rust-lang.org/u/theemathas)\
**Post date:** [October 1, 2026, 4:23am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/7 "2026-10-01T04:23:48Z")

</div>

Oh, there's a previous RFC for this. [RFC: impl trait expressions by canndrew · Pull Request #2604 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/pull/2604)

It's "postponed". It might be time to make a new RFC for it?

---

<div class="post-metadata">

**Author:** ![RealRTTV](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/realrttv/32/14592_2.png) [@RealRTTV](https://internals.rust-lang.org/u/RealRTTV)\
**Post date:** [October 1, 2026, 12:11pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/8 "2026-10-01T12:11:33Z")

</div>

I just updated the post contents; both cases would be restricted. The first wouldn't be allowed because it is not a singular trait bound. The second would not be allowed because an `impl` would be missing supertraits `A` and `B`.

---

<div class="post-metadata">

**Author:** ![RealRTTV](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/realrttv/32/14592_2.png) [@RealRTTV](https://internals.rust-lang.org/u/RealRTTV)\
**Post date:** [October 1, 2026, 12:12pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-trait-impls/24648/9 "2026-10-01T12:12:10Z")

</div>

Definitely, once I feel we've ironed it out well-enough here on the Pre-RFC.
