I am trying to create a generic structure that wraps isize
or AtomicIsize
, but I am AtomicIsize
error when I try to implement a trait for both possible implementations of the structure. I created a minimal example that demonstrates my problem below.
use std::sync::atomic::{AtomicIsize, Ordering}; use std::ops::Deref; use std::marker::PhantomData; pub trait Counted { fn inc(&self, value: isize); } pub type PlainCounter = isize; pub type AtomicCounter = AtomicIsize; pub struct Counter<'a, T: 'a> { counter: T, phantom: PhantomData<&'a T>, } impl<'a, T> Counter<'a, T> where T: Deref<Target = PlainCounter> { pub fn new(counter: T) -> Self { Counter { counter: counter, phantom: PhantomData, } } } impl<'a, T> Counted for Counter<'a, T> where T: Deref<Target = PlainCounter> { fn inc(&self, value: isize) { self.counter += 1; } } impl<'a, T> Counter<'a, T> where T: Deref<Target = AtomicCounter> { pub fn new(counter: T) -> Self { Counter { counter: counter, phantom: PhantomData, } } } impl<'a, T> Counted for Counter<'a, T> where T: Deref<Target = AtomicCounter> { fn inc(&self, value: isize) { self.counter.fetch_add(value, Ordering::SeqCst); } }
( playground )
The error I am getting is that the compiler found conflicting implementations of trait `Counted` for type `Counter<'_, _>`
. It seems that the compiler cannot determine that the implementations are for two different types of T
, namely T: Deref<Target = PlainCounter>
and T: Deref<Target = AtomicCounter>
. Maybe there is a way to provide additional information to the compiler so that it can distinguish between two cases, or am I on the wrong track entirely?
source share