# Can we avoid the orphan rule for empty traits?

**URL:** <https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642>\
**Category:** language design\
**Created:** [October 20, 2025, 10:53pm UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642 "2025-10-20T22:53:10Z")\
**Posts on this page:** 7\
**Page:** 1

<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:** [October 20, 2025, 10:53pm UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/1 "2025-10-20T22:53:10Z")

</div>

I recently had a situation where I wanted to use [`bytemuck::bytes_of`](https://docs.rs/bytemuck/latest/bytemuck/fn.bytes_of.html) to convert a reference to an object to a reference to the underlying bytes, but it requires the type implement the [`NoUninit` trait](https://docs.rs/bytemuck/latest/bytemuck/trait.NoUninit.html), and the type came from a crate that doesn't implement the trait even though the type meets the requirements.

Generally, for coherence purposes, the orphan rule is necessary to avoid having multiple implementations of the same trait for the same type, which could lead to ambiguity as to which implementation to use. But, in the case of this trait, there are no items in the implementation (no functions, constants, or associated types), so all implementations must be identical\[1\]. And semantically, these traits typically represent a property of the underlying type, such that implementing the trait is asserting the property and so it's idempotent to assert the same property multiple times.

I expect we'd probably want a lint to help people avoid accidentally implementing traits on external types when they don't mean to, but I see no reason why Rust couldn't allow something like this:

```rust
#[allow(impl_empty_external_trait_for_external_type)]
impl ExternalTrait for ExternalType {}

```

I think this would complicate negative trait bounds, since you can specify a type and trait and not locally know if the type implements that trait, and also specialization means you might have a concrete type and not know if it implements traits for one specialization or another. But as far as I can think of, nothing presently stable could cause a problem if this change happened.

* * *

1. `NoUninit` requires `Copy`, but if the crate implements `Copy` for a type, then downstream implementations of `NoUninit` must be identical

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [October 20, 2025, 11:07pm UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/2 "2025-10-20T23:07:47Z")

</div>

It was discussed and rejected for `marker` traits here:

> <https://github.com/rust-lang/rust/pull/96766>
>
> closes #67919, either by landing this or by officially deciding that we don't wa…nt this.
> I very much prefer to not land this change.
> 
> The reasoning for this was given by @Centril in #67919
> 
> \> In this specific case the user has marked the trait as \`#\[marker\]\` (and therefore it has no computational content and overlap is vacuously sound), so it seems to me that their intent was to allow this. Indeed, the reason I found this problem was that I wanted to move \[\`rustc::hir::ArenaAllocatable\`\](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/arena/trait.ArenaAllocatable.html) to \`rustc\_arena\`, but couldn't because of the orphan rule.
> 
> The original RFC from 2015 seems to imply that the orphan rules should be relaxed, but it was generally light on details. The impact this has on coherence was not mentioned there.
> 
> As downstream crates can now implement marker traits for arbitrary types, all \`MyType: MarkerTrait\` bounds have to either hold or are ambiguous. We can never prove that \`T: MarkerTrait\` does not hold. This prevents the snippet in the \`forbidden-fruit\` test.
> 
> While I am completely forbidding negative impls for marker traits here, we could allow them in the crate defining the marker trait. They still would be forbidden for impls of foreign marker traits for local types though.
> 
> cc https://github.com/rust-lang/rust/pull/68004#issuecomment-575760294
> 
> Mostly opened this to get a general consensus from @rust-lang/wg-traits that this is something we do not want ^^
> 
> r? @ghost

---

<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:** [October 21, 2025, 12:22am UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/3 "2025-10-21T00:22:30Z")

</div>

Sounds like you might be asking for this?

> **[marker\_trait\_attr - The Rust Unstable Book](https://doc.rust-lang.org/unstable-book/language-features/marker-trait-attr.html)**

* * *

EDIT: Oh, you're talking about Orphan, not Overlap?

Removing overlap is easy (with the trait opt-in to avoid semver hazards); removing orphan seems way more questionable.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [October 21, 2025, 12:30am UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/4 "2025-10-21T00:30:12Z")

</div>

> [@JarredAllen](#):
>
> And semantically, these traits typically represent a property of the underlying type, such that implementing the trait is asserting the property and so it's idempotent to assert the same property multiple times.

The orphan rule mechanically prevents multiple implementations, but it also protects a library author’s freedom to change how their type functions. If the type `foo::Bar` you were using is currently NoUninit-compatible in foo 1.0, well, that’s not normally an exposed property of a type, and so it might not be anymore in foo 1.1. Of course, that might be overly conservative—for example, if Bar’s members are all public and it satisfies all the bytemuck::NoUninit requirements in practice—so I’m not saying it can _never_ work, just pointing out that the orphan rule is theoretically justified as well as practically.

Auto traits are already an exception to this—occasionally a problematic one, if foo’s author didn’t realize a client was depending on Bar being Sync in 1.0, for example. Extending this to arbitrary traits would be…well, you can see there were previous discussions on it.

---

<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:** [October 21, 2025, 7:19pm UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/5 "2025-10-21T19:19:51Z")

</div>

Yeah, that is a potential concern, which is why I thought about having a lint you'd have to `#[allow]` to do the implementation. The error message on writing such an orphaned implementation should probably say something along those lines.

In my particular case that inspired this post, the type came from `libc` and is guaranteed to not have any uninitialized bytes, but `libc` doesn't take `bytemuck` as a dependency to implement its traits (which I think is the right choice for `libc`), nor does `bytemuck` take `libc` as a dependency to implement its traits on `libc` types (it could, but among other arguments against it, adding a big dependency would likely slow down compile times for dependents). So I'm stuck with a type that can't implement `NoUninit` for reasons of crate boundaries, but which otherwise could implement the trait, which is exactly when this would be useful.

---

<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:** [October 21, 2025, 8:35pm UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/6 "2025-10-21T20:35:52Z")

</div>

> [@JarredAllen](#):
>
> In my particular case that inspired this post, the type came from `libc` and is guaranteed to not have any uninitialized bytes, but `libc` doesn't take `bytemuck` as a dependency to implement its traits (which I think is the right choice for `libc`), nor does `bytemuck` take `libc` as a dependency to implement its traits on `libc` types

I've been thinking for a while that there should be some way for crates to say "compile this code only if this other crate exists in the crate graph within this version range", without being an actual dependency – that would allow that sort of interoperation between crates. (This is better than an optional dependency because if the other crate exists twice in the crate graph due to being imported with two different versions, you would get two copies of the code that requires both crates, in order to support both versions.)

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [October 21, 2025, 11:03pm UTC](https://internals.rust-lang.org/t/can-we-avoid-the-orphan-rule-for-empty-traits/23642/7 "2025-10-21T23:03:10Z")

</div>

> [@ais523](#):
>
> "compile this code only if this other crate exists in the crate graph within this version range", without being an actual dependency – that would allow that sort of interoperation between crates.

[Global features](https://internals.rust-lang.org/t/pre-rfc-mutually-excusive-global-features/19618) addresses this problem in some capacity.
