# Named impls and impl generics

**URL:** <https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158>\
**Category:** language design\
**Created:** [January 14, 2025, 8:55pm UTC](https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158 "2025-01-14T20:55:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![FZs](https://avatars.discourse-cdn.com/v4/letter/f/85f322/32.png) [@FZs](https://internals.rust-lang.org/u/FZs)\
**Post date:** [January 14, 2025, 8:55pm UTC](https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158/1 "2025-01-14T20:55:59Z")

</div>

Continuing the discussion from [Limited Opt Out of Orphan Rule](https://internals.rust-lang.org/t/limited-opt-out-of-orphan-rule/21709):

What I've been thinking about recently (which is kinda related) is named impls with anonymous or explicit impl generics.

This would be a very big change, so it is super unlikely to happen, but I thought I'd share it anyway, perhaps it's food for thought.

* * *

The idea is the following: in addition to normal impls that would continue to be subject to the orphan rules, one could create _named impls_.

(I'm going to use `$` for the syntax here, but it's up for bikeshedding)

```rust
impl<T> $name MyTrait<T> for T {}

```

Named impls could be created by any crate for any type/trait combination. Named impls could be imported/exported like traits, structs, enums, etc. Importantly, named impls are allowed to overlap with a normal impl or a different named impl, so this would be allowed:

```rust
impl<T> MyTrait for T {}
impl<T> $my_impl_1 MyTrait for T {}
impl $my_impl_2 MyTrait for MyStruct {}

```

Impl selection would happen wherever a concrete type is substituted for a type parameter. Impl selection would have an explicit syntax similar to fully qualified syntax, and some mechanism of eliding impl selection in an unambiguous way (just like lifetime elision is perfectly unambiguous from the syntax alone).

Then there would be the impl generics:

```rust
fn sort<$ordering: Ord, T: $ordering>(slice: &mut [T])

```

...which one could use like this:

```rust
impl $my_ordering Ord for i32 { ... }

let mut a = [1, 5, 8, 4, 2];

sort::<$my_ordering>(&mut a);
//or
sort((&mut a) as &mut [impl $my_ordering]) // this is ugly, we would need some better syntax

```

The "normal" trait bounds would act like anonymous impl generics. For backwards compatibility, different trait bounds on the same item would get the same impl generic.

```rust
fn foo<T: Add, U: Add>() {}
// would be roughly the same as
fn foo<$o: Add, T: $o, U: $o>() {}

```

I would actually want them to become separate impl generics, like this:

```rust
fn foo<T: Add, U: Add>() {}
// would be roughly the same as
fn foo<$o1: Add, $o2: Add, T: $o1, U: $o2>() {}

```

...but this would violate the expectation that `T::Output == U::Output` if `T == U`. I'm not sure how much this would be a problem in practice, but probably there is some case where it matters.

In a way, this feature could be used as a poor man's specialization. If I understand correctly, the problem holding back specialization is that the trait solver runs before the borrow checker analyses lifetimes, and the borrow checker is able to decide whether a specific system of lifetime constraints is satisfiable or not, but having the result of that feed back to impl selection is currently not possible.

My proposal would require _users_ to specify unambiguously which impl they want to use, and then the borrow checker could verify whether that choice works.

For example, the

```rust
impl From<T> for T {}

```

impl in the standard library could become named, which would allow crates to blanket impl `From<LocalType>` colliding with it. And then the user would have to specify at the call site which one they meant.

---

<div class="post-metadata">

**Author:** ![pitaj](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pitaj/32/11262_2.png) [@pitaj](https://internals.rust-lang.org/u/pitaj)\
**Post date:** [January 14, 2025, 10:35pm UTC](https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158/2 "2025-01-14T22:35:14Z")

</div>

Similar

> [@\[Pre-RFC\] Scoped \`impl Trait for Type\`](https://internals.rust-lang.org/t/pre-rfc-scoped-impl-trait-for-type/19923):
>
> Feature Name: scoped\_impl\_trait\_for\_type […] Summary This proposal adds scoped impl Trait for Type items into the core language, as coherent but orphan-rule-free alternative to implementing traits globally. It also extends the syntax of use-declarations to allow importing these scoped implementations into other item scopes (including other crates), and differentiates type identity of most generics by which scoped trait implementations are available to each discretised generic type parameter (…

---

<div class="post-metadata">

**Author:** ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)\
**Post date:** [January 16, 2025, 9:52pm UTC](https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158/3 "2025-01-16T21:52:25Z")

</div>

it's worth noting that `$` cannot be used for this, as this would make it impossible to mix with declarative macros.

---

<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:** [January 21, 2025, 7:42pm UTC](https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158/4 "2025-01-21T19:42:23Z")

</div>

You can (on nightly, at least) use `$$` inside the body of a declarative macro to expand to just a single `$` token ([unstable because of uncertainty over exactly which crate `$$crate` refers to](https://github.com/rust-lang/rust/issues/83527)). You can also use a `tt` to match a `$` token and then use that variable to expand to that `$` where you need it.

It'd probably be better to avoid something that requires one of these workarounds, but this syntax is possible to mix with declarative macros.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [July 15, 2026, 7:43pm UTC](https://internals.rust-lang.org/t/named-impls-and-impl-generics/22158/5 "2026-07-15T19:43:06Z")

</div>

This topic was automatically closed 540 days after the last reply. New replies are no longer allowed.
