Skip to content

Commit

Permalink
Refactor: Fix: impl XX for associated type conflict in another crate
Browse files Browse the repository at this point in the history
This commit addressed an issue of implementing trait for associated
types, by replacing implementation for associated type with concrete
type `pb::Vote`.

- Related issues: rust-lang/rust#51445

- The minimized reproduce repo is:
  https://github.com/drmingdrmer/conflict-trait-in-main

Explanation:

If one crate `lib.rs` implements a trait(`Default`) for an associated
type(`<() as Container>::Item`, which is `Foo`), in another crate
`main.rs`, it seems the compiler treats the associated type(`<() as
Container>::Item`) as a generic type `T` and assumes `T` would
be any type and results in the conflict with a local type that tries to
implement `Default`, while actually `Foo` and `Wow` are actually
different types.

cargo repo:

```
▾ src/
    lib.rs
    main.rs
```

`lib.rs`:

```rust
pub trait Container {
    type Item;
}

impl Container for () {
    type Item = Foo;
}

pub struct Foo;

impl Default for <() as Container>::Item {
    fn default() -> Self { Foo }
}
```

`main.rs`:

```rust
// Make main.rs depends on lib.rs
use t_conflict::Container as _;

struct Wow;
impl Default for Wow {
    fn default() -> Self { Wow }
}

fn main() {}
```

`cargo build` yield this error:
```
error[E0119]: conflicting implementations of trait `Default` for type `Wow`
 --> t-conflict/src/main.rs:7:1
  |
7 | impl Default for Wow {
  | ^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `t_conflict`:
          - impl Default for <() as Container>::Item;
```
  • Loading branch information
drmingdrmer committed Mar 5, 2025
1 parent f5790c5 commit 7f85719
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions examples/raft-kv-memstore-grpc/src/pb_impl/impl_vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use std::fmt;

use openraft::vote::RaftVote;

use crate::typ::*;
use crate::pb;
use crate::typ::LeaderId;
use crate::TypeConfig;

impl RaftVote<TypeConfig> for Vote {
impl RaftVote<TypeConfig> for pb::Vote {
fn from_leader_id(leader_id: LeaderId, committed: bool) -> Self {
Vote {
pb::Vote {
leader_id: Some(leader_id),
committed,
}
Expand All @@ -22,7 +23,7 @@ impl RaftVote<TypeConfig> for Vote {
}
}

impl fmt::Display for Vote {
impl fmt::Display for pb::Vote {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
Expand Down

0 comments on commit 7f85719

Please sign in to comment.