Rust Error E0592: Duplicate Definitions With Name X
E0592 means: the same type has two methods, associated functions or constants with the same name, written in impl blocks. A type can have as many impl blocks as you like, but all of them share one list of names, so each name can be used only once. It usually comes from copy-paste, a merge, or a second impl block in another file. The fix is to keep one, or give the other a new name. (This page is part of Rust compiler errors explained.)
The error message
Section titled “The error message”error[E0592]: duplicate definitions with name `reset` --> src/main.rs:10:5 |10 | fn reset(&mut self) { | ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `reset`...16 | fn reset(&mut self) { // ❌ `reset` is already defined above | ------------------- other definition for `reset`This is the program that produces it:
struct Counter { count: u32,}
impl Counter { fn new() -> Self { Counter { count: 0 } }
fn reset(&mut self) { self.count = 0; }}
impl Counter { fn reset(&mut self) { // ❌ `reset` is already defined above self.count = 0; }}
fn main() { let mut c = Counter::new(); c.reset(); println!("{}", c.count);}rustc also reports E0034, “multiple applicable items in scope”, at the call c.reset(), because it can’t tell which of the two resets you mean. That’s a follow-up error: fix E0592 and E0034 goes away too.
What it means
Section titled “What it means”The headline gives the name that’s defined twice (reset). The ^^^ marks one definition, and the --- line marks the “other definition”. rustc shows the line numbers of both, so you can jump straight to them. When they’re far apart, the ... in between just means “some lines skipped”.
It doesn’t matter that the two resets are in different impl Counter blocks, or even in different files of your crate. For Rust they’re all methods of the same type, so Counter::reset must mean exactly one function. The same rule applies to associated constants: two const MAX: u32 for one type is also E0592.
It’s like a phone’s contact list with two entries called “Mum”. When you say “call Mum”, which number should it dial?
Why Rust does this
Section titled “Why Rust does this”Splitting methods over several impl blocks is allowed and often useful: one block for constructors, one for getters, one behind a #[cfg(test)]. See Adding behavior with methods. But when you call c.reset() or Counter::reset(&mut c), Rust has to find one function. If there were two, which one runs would depend on details nobody can see by reading the call.
So Rust refuses at the definition, not just at the call. This catches a real bug: with a copy-pasted method you might fix a problem in one copy, and the other copy keeps running. Rust makes sure there’s only ever one version to fix.
How to fix it
Section titled “How to fix it”Fix 1: Delete the duplicate and keep one definition
Section titled “Fix 1: Delete the duplicate and keep one definition”Choose this most of the time. If both copies do the same thing (copy-paste, a messy merge, a method you moved but didn’t remove), delete one. Before you delete, compare the two bodies: if one has a fix the other doesn’t, keep that one. Merging the impl blocks into one also makes duplicates easier to spot in the future.
struct Counter { count: u32,}
impl Counter { fn new() -> Self { Counter { count: 0 } }
fn increment(&mut self) { self.count += 1; }
fn reset(&mut self) { // ✅ only one `reset` for `Counter` self.count = 0; }}
fn main() { let mut c = Counter::new(); c.increment(); c.increment(); println!("before reset: {}", c.count); c.reset(); println!("after reset: {}", c.count);}Output:
before reset: 2after reset: 0If you can’t find the second definition, search the whole project: grep -rn "fn reset" src/. An impl Counter block can live in any module of your crate.
Fix 2: Rename one of them
Section titled “Fix 2: Rename one of them”Choose this when the two definitions do different things. Rust has no overloading: you can’t have two methods with the same name and different parameters, like reset() and reset(start: u32). That’s also E0592. Give each a name that says what it does:
struct Counter { count: u32,}
impl Counter { fn new() -> Self { Counter { count: 0 } }
fn reset(&mut self) { self.count = 0; }}
impl Counter { fn reset_to(&mut self, start: u32) { // ✅ a different name for different behavior self.count = start; }}
fn main() { let mut c = Counter::new(); c.reset_to(10); println!("after reset_to(10): {}", c.count); c.reset(); println!("after reset(): {}", c.count);}Output:
after reset_to(10): 10after reset(): 0Common Rust naming patterns help here: new and with_capacity, from_str and from_bytes, get and get_mut. If you really want one name for several argument types, use a generic parameter or a trait, like fn reset_to(&mut self, start: impl Into<u32>). See Generics.
Fix 3: Stop generic impl blocks from overlapping
Section titled “Fix 3: Stop generic impl blocks from overlapping”Choose this when one of the two definitions is in a generic block like impl<T> Wrapper<T>. That block covers Wrapper<i32> too, so a second impl Wrapper<i32> with the same method name is a duplicate:
error[E0592]: duplicate definitions with name `describe` --> src/main.rs:4:5 | 4 | fn describe(&self) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `describe`...10 | fn describe(&self) -> String { | ---------------------------- other definition for `describe`The program behind it:
struct Wrapper<T>(T);
impl<T> Wrapper<T> { fn describe(&self) -> String { String::from("something") }}
impl Wrapper<i32> { fn describe(&self) -> String { format!("the number {}", self.0) }}
fn main() { println!("{}", Wrapper(5).describe());}Rust doesn’t let a specific impl override a generic one (that feature, called specialization, isn’t stable). Two good ways out: write impl blocks only for specific types, so they can’t overlap, or put the behavior in a trait and implement it once per type:
struct Wrapper<T>(T);
// Option A: impl blocks for specific types never overlapimpl Wrapper<i32> { fn describe(&self) -> String { format!("the number {}", self.0) }}
impl Wrapper<&str> { fn describe(&self) -> String { format!("the text \"{}\"", self.0) }}
// Option B: a trait, implemented once per typetrait Label { fn label(&self) -> String;}
impl Label for i32 { fn label(&self) -> String { format!("int {}", self) }}
impl Label for bool { fn label(&self) -> String { format!("flag {}", self) }}
impl<T: Label> Wrapper<T> { fn label(&self) -> String { self.0.label() // one generic method, the per-type part lives in the trait }}
fn main() { println!("{}", Wrapper(5).describe()); println!("{}", Wrapper("hi").describe()); println!("{}", Wrapper(7).label()); println!("{}", Wrapper(true).label());}Output:
the number 5the text "hi"int 7flag trueThe trait version is usually the better long-term design: adding support for a new type is just one more impl Label for .... See Traits.
Where you’ll usually see it
Section titled “Where you’ll usually see it”A test helper in a second impl block. You add impl Counter { fn new() -> Self { ... } } inside #[cfg(test)] mod tests to build test values, but Counter::new already exists. The test block is still an impl Counter. Fix: name it something like fn for_test(), or use the real new. See Testing.
After a merge or refactor. Two branches both added a fn len(&self), or a method was moved to a new file and the old copy stayed. rustc shows both line numbers; keep the better one.
A trait method with the same name is fine. impl Counter { fn reset(&mut self) } together with impl Resettable for Counter { fn reset(&mut self) } is not E0592: one is the type’s own method, the other belongs to the trait, and c.reset() calls the type’s own one. Two traits with the same method name compile too, but calling it with c.reset() gives E0034; fix that with Resettable::reset(&mut c).
Related errors
Section titled “Related errors”- E0034: multiple applicable items in scope: the follow-up error at the call site, and the error for two traits with the same method name.
- E0428: the name is defined multiple times: the same mistake for items in a module, like two
struct Counteror two free functionsfn main. - E0599: no method named x found: the opposite problem, a method that doesn’t exist at all.
- E0255: name already used by an import and E0252: name imported twice: duplicate names caused by
use. - All compiler errors explained
Quick check
Section titled “Quick check”Quick check
1. A type has two impl blocks. Can both contain a method called reset?
2. You want area() and area(scale: f64). What do you do in Rust?
3. Why do impl<T> Wrapper<T> and impl Wrapper<i32> clash when both define describe?
Score: 0 / 3
Read more
Section titled “Read more”- E0592 — Rust error codes index: the official explanation of this error.
- Method Syntax — The Rust Book: methods, associated functions and “Multiple
implBlocks”. - Generic Data Types — The Rust Book:
impl<T> Point<T>next toimpl Point<f32>, and how they relate. - Implementations — The Rust Reference: the exact rules for inherent
implblocks and their associated items. - E0034 — Rust error codes index: the official page for the follow-up “multiple applicable items” error.