# \[Idea\] Explicitly imported orphan impls

**URL:** <https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731>\
**Category:** language design\
**Created:** [August 8, 2017, 9:16am UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731 "2017-08-08T09:16:14Z")\
**Posts on this page:** 7\
**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:** [August 8, 2017, 9:16am UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/1 "2017-08-08T09:16:14Z")

</div>

I’ve been thinking a bit on the troubles with orphan impls. There were multiple ideas on how to make them work automagically. But why don’t we simply allow them to be normal module members, with ability to use or not use in certain scope?

- Unlike current situation, allow trait impl to be declared anywhere
- Trait impl gets into action only if either:
  - It’s explicitly imported into scope via something like `use othercrate::impl Ord;`
  - It resides in the same crate as either trait or type

As a possible modification, we may make current impl rules a bit more consistent (albeit, it requires to carefully check current codebase so that nothing would break):

- Do not make arbitrarily located impl visible, even if it’s located in the same crate as its trait or target (that’s the breaking change)
- But make impls “stick” to their trait or target, if they’re in the same module. Such “sticky” impl is implicitly visible when the thing it sticks to is used.

This should keep everything nicely coherent - and leave room for manual resolution.

Thoughts?

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [August 8, 2017, 12:24pm UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/2 "2017-08-08T12:24:32Z")

</div>

It's been proposed a few times:

> [@Named and scoped trait implementations as a solution to orphan rules \[ok, it wont' work\]](https://internals.rust-lang.org/t/named-and-scoped-trait-implementations-as-a-solution-to-orphan-rules-ok-it-wont-work/4711/10):
>
> We initially had scoped impls in Rust. We removed them because of what we called “the hashtable problem”. This [e-mail of mine from 2011](https://mail.mozilla.org/pipermail/rust-dev/2011-December/001036.html) kind of goes into some of the details, I think. We called it the hashtable problem because – imagine you had a hashtable with keys to type K that is built up using one impl of Hash, but then you pass that hashtable to another module, where a distinct Hash impl is in scope. It’s going to be pandemonium. What that e-mail proposed was to solve this by making the im…

---

<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:** [August 8, 2017, 12:45pm UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/3 "2017-08-08T12:45:08Z")

</div>

Okay, I suspected it to be too simple and obvious to be overlooked by core team.

---

<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:** [August 9, 2017, 8:37am UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/4 "2017-08-09T08:37:38Z")

</div>

Maybe someone knows how Golang handles such coherence? They basically have duck-typed interfaces, based on functions currently in scope. So this could be as well issue for them too. Couldn’t google out anything reasonable.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [August 9, 2017, 6:51pm UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/5 "2017-08-09T18:51:38Z")

</div>

Looks like you can’t extend the behavior of existing types in Go: [https://stackoverflow.com/questions/28800672/how-to-add-new-methods-to-an-existing-type-in-go](https://stackoverflow.com/questions/28800672/how-to-add-new-methods-to-an-existing-type-in-go)

They have an “alias” functionality which acts like our newtype pattern.

---

<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:** [August 9, 2017, 7:08pm UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/6 "2017-08-09T19:08:50Z")

</div>

So they have something similar to Rust orphan rules I guess.

---

<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:** [March 25, 2019, 8:28am UTC](https://internals.rust-lang.org/t/idea-explicitly-imported-orphan-impls/5731/7 "2019-03-25T08:28:53Z")

</div>

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