Description
I ran into a coherence problem where I think that the compiler is too strict, even though the code should be accepted according to the coherence rules (as far as I can tell).
For the code below, the compiler will report
error[E0210]: type parameter `<MyString as somelib::ConvertTo>::Output` must be used as the type parameter for some local type ...`,
but passing O
explicitly (for ItemOrConverted<MyString, String>
) works.
The code:
/// In some other crate.
trait ConvertTo {
type Output;
}
enum ItemOrConverted<T: ConvertTo, O = <T as ConvertTo>::Output> {
Item(T),
Converted(O),
}
/// In our crate.
struct MyString { }
impl ConvertTo for MyString {
type Output = String;
}
impl PartialEq<MyString> for ItemOrConverted<MyString> {
fn eq(&self, other: &MyString) -> bool {
unimplemented!();
}
}
I have a trait with an associated type (ConvertTo::Output
, in the example below), and an enum which is generic over T: ConvertTo
and generic over O
with a default value for O
based on the associated type from T
's ConvertTo
, all in one crate.
In another crate I have MyString
, and I would like to implement PartialEq<MyString>
for this enum over MyString
, but without changing the default value for O
. (Think impl PartialEq<MyString> for Cow<MyString>
).
Is this really allowed "in theory" by the coherence rules or am I missing something?
(edit: Compiling with #![feature(re_rebalance_coherence)]
works!)
Meta
rustc 1.37.0-nightly (37d001e 2019-05-29)
binary: rustc
commit-hash: 37d001e
commit-date: 2019-05-29
host: x86_64-pc-windows-msvc
release: 1.37.0-nightly
LLVM version: 8.0