# Opt-in to overlapping impls and explicit impl selection

**URL:** <https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029>\
**Category:** language design\
**Created:** [July 15, 2021, 6:21pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029 "2021-07-15T18:21:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 15, 2021, 6:21pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/1 "2021-07-15T18:21:12Z")

</div>

there should be a way for a trait to opt-in to non-specializable overlapping impls and require explicit impl selection at use. additionally, a set of "preferred" impls can be provided, so that a currently non-overlapping trait can bemade overlapping. this would be especially useful for Pattern, to make it accept Fn(&char) in addition to Fn(char).

for example, you could have an overlapping trait:

```rust
overlapping trait Pattern<'a> {
  ...
}

```

and then preferred impls (which act just like existing impls):

```rust
// syntax chosen to allow transforming a trait into an overlapping trait backwards-compatibly
// aka we just use existing syntax for non-overlapping impls
impl<'a, 'b> Pattern<'a> for &'b str {
  ...
}

...

```

and then the new overlapping impls:

```rust
// these don't participate in normal impl resolution
overlapping impl<'a, F> Pattern<'a> for F where F: FnMut(&char) -> bool {
  ...
}

```

when using a function, unless impl selection syntax is used, only the preferred impls are visible. (this can be broadened later, but it would introduce backwards-compatibility caveats similar to the IntoIterator/Deref interaction we had with arrays.) in other words:

```rust
// these all check the preferred impls
"foo".find("bar");
"foo".find('a');
"foo".find(['a', 'b']);
// this also checks the preferred impls, so it infers FnMut(char) -> bool
"foo".find(|c| c == 'a');

```

that is to say all existing code would remain working.

additionally, you'd be able to write this:

```rust
"foo".find<_: (impl<'a, F> Pattern<'a> for F where F: FnMut(&char) -> bool)>(char::is_ascii_lowercase);

```

which is very verbose, but makes a good starting point. (as we said, this can be broadened later, but it would introduce backwards-compatibility caveats similar to the IntoIterator/Deref interaction we had with arrays.)

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [July 15, 2021, 7:10pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/2 "2021-07-15T19:10:45Z")

</div>

As with nearly every one of your posts, can you please provide some more detail?

---

<div class="post-metadata">

**Author:** ![ibraheemdev](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ibraheemdev/32/13406_2.png) [@ibraheemdev](https://internals.rust-lang.org/u/ibraheemdev)\
**Post date:** [July 15, 2021, 9:16pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/3 "2021-07-15T21:16:30Z")

</div>

You mean something like this?

```rust
unsafe? { #![allow(overlapping_impls_that_can_cause_unsoundness_but_i_dont_care)] }

impl<T> Deref for T {
    type Output = str;

    fn deref(&self) -> &Self::Output { "foo" }
}

```

---

<div class="post-metadata">

**Author:** ![wiogit](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/wiogit/32/5711_2.png) [@wiogit](https://internals.rust-lang.org/u/wiogit)\
**Post date:** [July 15, 2021, 9:46pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/4 "2021-07-15T21:46:47Z")

</div>

I created a [trait mask topic](https://internals.rust-lang.org/t/idea-trait-mask/15013/10) a couple days ago which overlaps with this concept.

Do you have a specific plan for how someone would designate and invoke an alternative implementation without a wrapper class?

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 15, 2021, 9:53pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/6 "2021-07-15T21:53:11Z")

</div>

> [@jhpratt](#):
>
> As with nearly every one of your posts, can you please provide some more detail?

kinda hard to provide more detail when you don't know what the syntax for it would look like.

the basic idea is:

1. the trait has to opt-in to it
2. impls of the trait can be overlapping
3. you choose which trait impl to use at use location, probably through using the impl line, without the impl block obviously.

> [@ibraheemdev](#):
>
> You mean something like this?

more like:

```rust
overlapping trait Foo {
}

impl<T> Foo for T where T: Bar {
}

impl<T> Foo for T where T: Baz {
}

impl Foo for MyThing {
}

fn foo<T: Foo>(t: T) {
}

foo<_: (impl<T> Foo for T where T: Bar)>(MyThing); // inference
foo<MyThing: (impl<T> Foo for T where T: Bar)>(MyThing); // explicit
foo<_: (impl Foo for MyThing)>(MyThing); // oh yes

```

this can currently be emulated with newtypes as follows:

```rust
#[repr(transparent)]
pub struct FooForBar<T>(T);

impl<T> Foo for FooForBar<T> where T: Bar {
}

impl<T> FooForBar<T> {
  pub fn from(t: T) -> FooForBar<T> {
    FooForBar(t)
  }
  pub fn from_ref(t: &T) -> &FooForBar<T> {
    unsafe { ... }
  }
  pub fn from_mut(t: &mut T) -> &mut FooForBar<T> {
    unsafe { ... }
  }
}

```

but obviously the newtype-based approach requires the use of `unsafe {}` for the ref/mut projections (and doesn't play the nicest with Pin unless you also do from\_pin and whatnot).

also, one obvious restriction is that you wouldn't be able to create non-overlapping impls bounded by overlapping traits, so the following would be an error:

```rust
trait Qux {
}
impl<T: Foo> Qux for T { // error: Foo is overlapping
}
impl<T: (impl<T> Foo for T where T: Bar)> Qux for T { // this is allowed tho
}

```

---

<div class="post-metadata">

**Author:** ![yaahc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/yaahc/32/6606_2.png) [@yaahc](https://internals.rust-lang.org/u/yaahc)\
**Post date:** [July 15, 2021, 11:48pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/7 "2021-07-15T23:48:21Z")

</div>

What's the usecase for this? If you already have to be explicit about which impl to use I don't see how it helps to have the impls be attached to the same trait. You can already create ambiguous method calls by having multiple traits in scope define the same method. How is this different?

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 12:08am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/8 "2021-07-16T00:08:18Z")

</div>

Rust doesn't (currently) support newtype projections, and we don't know of any proposals for it either. This isn't newtype projections but it does cover at least one use-case of newtype projections.

---

<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:** [July 16, 2021, 12:31am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/9 "2021-07-16T00:31:24Z")

</div>

There are other ways to do this in addition to newtypes.

For example, you can pass a strategy type parameter (probably a ZST or phantom) that defaults to the usual impl, but a different strategy type can have a different implementation.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 12:43am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/10 "2021-07-16T00:43:20Z")

</div>

That's not really straightforward tho. We can think of Pattern as being somewhat annoying, for example. Granted, you can't make Pattern overlapping because overlapping requires explicitly passing in the impl, and that would be breaking, but in new APIs it would allow impl'ing for various Fn types.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [July 16, 2021, 1:14am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/11 "2021-07-16T01:14:35Z")

</div>

Back in 2017 you [proposed](https://github.com/rust-lang/rfcs/issues/2197) this same feature [twice](https://github.com/rust-lang/rfcs/issues/2251). Both times you were criticized for not being detailed enough. This time your post is even shorter than those were.

It's not a bad idea, and I have no objection to revisiting the same topic when more than 3 years have passed, but if you can't improve your writing then this will end up the same way it did in 2017.

---

<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:** [July 16, 2021, 1:55am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/12 "2021-07-16T01:55:12Z")

</div>

> [@Soni](#):
>
> Rust doesn't (currently) support newtype projections

> [@Soni](#):
>
> the newtype-based approach requires the use of `unsafe {}` for the ref/mut projections

General newtype ref casts are not safe, because the newtype could have additional safety requirements.

At a library level, newtype ref casts are provided by the [ref-cast crate](https://lib.rs/crates/ref-cast). It currently only provides `&T -> &U` and `&mut T -> &mut U` casts, but could easily be extended (or a similar derive macro written) to provide casts for other receivers.

At a language level, ref casts are provided by [project safe transmute](https://github.com/rust-lang/project-safe-transmute).

---

<div class="post-metadata">

**Author:** ![ibraheemdev](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ibraheemdev/32/13406_2.png) [@ibraheemdev](https://internals.rust-lang.org/u/ibraheemdev)\
**Post date:** [July 16, 2021, 2:59am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/13 "2021-07-16T02:59:29Z")

</div>

Related:

- [Crates should allow private impl of external traits for external structs · Issue #493 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/issues/493)

Edit: Although I don't fully understand the proposal.. so might not be related.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 4:13am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/14 "2021-07-16T04:13:22Z")

</div>

Named impls is still a good idea, but it's also different from this. Because named impls have names, it would make sense/be possible to have them on a trait that isn't marked overlapping. (Altho this would probably be an issue for the existing Any trait.) They do more or less solve the same problems tho.

Given the syntax we used above (`foo<_: (impl Foo for Bar)>()`), it would also be possible to use a similar syntax for named impls: `foo<_: ImplName>()`. So we guess we are revisiting it over 3 years later, now with syntax? :‌p

(Altho we also think named impls is _intended_ to interact weirdly with method resolution, based on which named impls you import in a given context? E.g. if you import the named impls from `wrapping_ops::*`, all your integers are wrapping, but if you import the named impls from `panicking_ops::*` then they panic instead? Which is completely different from this proposal, where they would be excluded from method resolution.)

Anyway: you keep saying we need to say more about the idea of overlapping impls but _we keep coming up empty on what to say_. What else do you want to hear? What's missing? What's so obvious to us that isn't so obvious to you? What if we don't have the answers you're looking for?

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 4:18am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/15 "2021-07-16T04:18:25Z")

</div>

> [@CAD97](#):
>
> General newtype ref casts are not safe, because the newtype could have additional safety requirements.

The main use case for this proposal is actually overloading on Fn traits, in places similar to Pattern. (but not Pattern itself, because doing it to Pattern would be breaking.)

What kind of additional safety requirements can you actually put on that?

Besides, we never said it shouldn't be opt-in. There's no reason we can't mark _specific_ newtypes as being freely castable other than it not being implemented.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [July 16, 2021, 4:26am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/16 "2021-07-16T04:26:43Z")

</div>

Can you please provide a clear use case where this is the only feasible option, including why the newtype pattern would be detrimental?

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 4:34am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/17 "2021-07-16T04:34:07Z")

</div>

Not really, because this is equivalent to, effectively, a subset of newtypes, just with different tradeoffs (mostly, being a subset).

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [July 16, 2021, 4:36am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/18 "2021-07-16T04:36:10Z")

</div>

As I said, please provide a use case where the newtype pattern would be detrimental. If you can't do so much as provide a _single use case_, why should anyone take this seriously?

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 4:43am UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/19 "2021-07-16T04:43:37Z")

</div>

It's meant to be uh, hm...

"open" newtypes that can be freely casted would probably be easier to implement in the language, but eh it really does _not_ hurt to suggest alternatives.

it's not about whether it's detrimental. it's about what you can do with it. yes you can do it with newtypes, you can have a CharMatcher(Fn(char) -\> bool) and a CharRefMatcher(Fn(&char) -\> bool), or you can have opt-in overlapping impls. it's two ways of doing more-or-less the same thing.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [July 16, 2021, 10:13pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/20 "2021-07-16T22:13:00Z")

</div>

Updated OP with new details.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [July 16, 2021, 11:12pm UTC](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029/21 "2021-07-16T23:12:38Z")

</div>

This is where you should _start_ with future posts. I still disagree with the premise, and OP could still use some more details as to benefits and drawbacks, but it's much better than what you had before.

[Next page](https://internals.rust-lang.org/t/opt-in-to-overlapping-impls-and-explicit-impl-selection/15029.md?page=2)
