Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Fix: impl XX for associated type conflict in another crate #1331

Merged
merged 3 commits into from
Mar 5, 2025

Conversation

drmingdrmer
Copy link
Member

@drmingdrmer drmingdrmer commented Mar 5, 2025

Changelog

Refactor: Fix: impl XX for associated type conflict in another crate

This commit addressed an issue of implementing trait for associated
types, by replacing implementation for associated type with concrete
type pb::Vote.

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.

▾ src/
    lib.rs
    main.rs

lib.rs:

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:

// 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;

This change is Reviewable

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;
```
Upgrade tip:

`SnapshotSignature.last_membership_log_id` changes from `Option<LogId>`
to `Option<Box<LogId>>`.
@drmingdrmer drmingdrmer merged commit ac2b720 into databendlabs:main Mar 5, 2025
64 of 65 checks passed
@drmingdrmer drmingdrmer deleted the 181-fix-example branch March 5, 2025 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants