trait C {}
trait A {}
impl<I: A> C for I {}
trait B {}
impl<I: B> C for I {}
でもエラーになる。
Compiling playground v0.0.1 (/playground)
error[[E0119]](https://doc.rust-lang.org/stable/error-index.html#E0119): conflicting implementations of trait `C`
--> src/main.rs:7:1
|
4 | impl<I: A> C for I {}
| ------------------ first implementation here
...
7 | impl<I: B> C for I {}
| ^^^^^^^^^^^^^^^^^^ conflicting implementation
For more information about this error, try `rustc --explain E0119`.
error: could not compile `playground` due to previous error
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1f6e1fbe833caa1a9fd5939e64363d19
trait C {}
trait A {}
impl<I: A> C for I {}
trait B {}
impl<I: B> C for I {}
struct Hoge {}
impl A for Hoge {}
impl B for Hoge {}
// Hogeに対してどっちのCの実装をつかえばいい?
現状、rust-dapのトレイトのうち、
BitBangSwdIo
やPrimitiveSwdIo
は上位のトレイトの汎用の実装を持っている。SWDだけだとこれでよかったが、JTAG用の型も追加すると、
CmsisDapCommandInner
の汎用実装をJTAG用の型に対しても追加したくなる。実際にこのような構成にすると、
PrimitiveJtagIo
に対するCmsisDapCommandInner
の箇所でエラーになる。もっと単純化して、
でもエラーになる。
これは、ジェネリクスを用いたトレイトの汎用実装は、高々一つまでしか許可されないからで、rustcのissueにも古くから上がっているようだが、現在のところ解決策は出ていない。
まあ、よくよく考えてみれば、汎用実装を提供している2つのトレイトを実装した型があった場合、どちらの実装を用いるのか解決できなくなるので当たり前のような気もする。 (C++の多重継承の問題に近い)
なので、現状のrust-dapにおける
CmsisDapCommandInner
の汎用実装の課題も同様であるが、どう対応すべきか悩ましい。現状は
CmsisDapCommandInner
に対する汎用実装はPrimitiveSwdIo
実装型に対してのみ提供しており、JTAG側の型には提供していないという非対称な定義で対策をしているが、本来は対象であるべき。なにかいい方法を考えたい。