E0116
Rust Programming Language
Severity: ModerateWhat Does This Error Mean?
Rust error E0116 means you are trying to add methods (an inherent impl block) directly to a type that was defined in another crate. Rust's coherence rules prohibit this to ensure the type's behavior is consistent everywhere it is used. You cannot write impl Vec<i32> { fn my_method(...) } in your own crate because Vec is defined in the standard library. The solutions are to use a newtype wrapper, define a trait and implement it for the external type, or use extension traits.
Affected Models
- Rust 1.70+
- Rust 1.80+
- cargo build
- rustc compiler
- Any Rust project
Common Causes
- Attempting to add methods to a standard library type (Vec, String, HashMap, etc.) using an inherent impl block
- Writing impl SomeExternalType { ... } where SomeExternalType comes from a dependency crate
- Trying to extend a third-party library type with new methods without using a trait
- Misunderstanding that impl blocks on external types require the trait approach, not direct impl
- Refactoring code from a single crate into multiple crates without updating impl placement
How to Fix It
-
Use a newtype wrapper. Create a struct that wraps the external type: struct MyVec(Vec<i32>); — then write impl MyVec { fn my_method(&self) { ... } }. You own MyVec, so inherent impl is allowed.
The newtype pattern is idiomatic Rust for adding behavior to external types. The wrapper has zero runtime cost.
-
Define a trait and implement it for the external type. Create your own trait with the methods you want, then implement it for the external type: impl MyTrait for Vec<i32> { ... }.
This is the extension trait pattern. The trait must be in scope (imported) wherever you want to use the new methods.
-
Use a free function instead of a method. Instead of adding my_method to Vec, write: fn process_vec(v: &Vec<i32>) { ... }. Free functions work without any impl constraints.
Free functions are the simplest solution when you only need the behavior in one place and do not need method syntax.
-
If the external type comes from a dependency you control (your own workspace crate), move the impl block to the crate that defines the type.
In a Cargo workspace with multiple crates, impl blocks on a type must live in the same crate that defines that type.
-
Consider if you actually need to extend the type at all. Rust's standard library types have extensive APIs. Check the documentation for existing methods before adding new ones.
Run 'cargo doc --open' or visit doc.rust-lang.org to browse all available methods on standard library types.
When to Call a Professional
E0116 is a compile error about Rust's coherence rules — no external service is needed. This is a design decision in your code architecture that you resolve by choosing one of the patterns described below.
Frequently Asked Questions
What is the orphan rule in Rust?
The orphan rule (also called the coherence rule) states that you can only implement a trait for a type if either the trait or the type is defined in your crate. You cannot implement an external trait for an external type. This rule exists so that Rust can guarantee no two crates provide conflicting implementations of the same trait for the same type. E0116 is the specific error for inherent impls (not trait impls) on external types.
What is the newtype pattern and when should I use it?
The newtype pattern wraps an existing type in a single-field struct: struct Wrapper(ExistingType); You then implement methods and traits on Wrapper instead of on ExistingType. Use it when you need to add behavior to an external type or when you want a distinct type (for type safety) that has the same underlying representation. The wrapper has zero memory overhead — it compiles to the same code as using the inner type directly.
Can I implement a standard library trait for an external type?
Yes, as long as either the trait or the type is local to your crate — but not both external. For example, you can implement Display (std library trait) for YourType (your type) — that is allowed. You can also implement YourTrait (your trait) for Vec<i32> (std type) — that is also allowed. You cannot implement Display for Vec<i32> in your crate because both are external — that violates the orphan rule (E0117).