'Why am I required to "cover" T in `impl ForeignTrait<LocalType> for T` [E0210]
Today I ran into a pretty strange error message that I'm having a hard time understanding. Consider this easy map-entry-like struct:
struct Entry<K, V> {
key: K,
value: V
}
Now, I want to implement all the std::cmp traits between Entry<K, V> with itself and with just K. Let's focus on PartialEq for now. These two implementations work just fine:
impl<K: PartialEq, V> PartialEq for Entry<K, V> { /* ... */ }
impl<K: PartialEq, V> PartialEq<K> for Entry<K, V> { /* ... */ }
But the last one gives me a hard time (Playground)
impl<K: PartialEq, V> PartialEq<Entry<K, V>> for K {
fn eq(&self, other: &Entry<K, V>) -> bool {
self.eq(&other.key)
}
}
The error message, as far as I can understand it, claims I'd be using a non-local type as the first parameter of the foreign trait. However, Entry ist defined locally in the same file.
error[E0210]: type parameter
Kmust be covered by another type when it appears before the first local type (Entry<K, V>)--> src/lib.rs:6:6 | 6 | impl<K: PartialEq, V> PartialEq<Entry<K, V>> for K { | ^ type parameter `K` must be covered by another type when it appears before the first local type (`Entry<K, V>`) |note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
note: in this case, 'before' refers to the following order:impl<..> ForeignTrait<T1, ..., Tn> for T0, whereT0is the first andTnis the last
Can someone explain why I am getting this error message, what the error and especially uncovered means and why this implementation is disallowed?
Solution 1:[1]
I think you want the other way around:
impl<K: PartialEq, V> PartialEq<K> for Entry<K, V> {
fn eq(&self, other: &K) -> bool {
self.key.eq(&other)
}
}
As for why your direction does not work: Imagine someone defines a struct that can be compared to anything:
struct K;
impl<V> PartialEq<V> for K { // V could be anything (including your struct Entry)
fn eq(&self, other: &V) -> bool {
true
}
}
Now, there would be conflicting impls for K and your Entry.
Solution 2:[2]
you could use next() to find the first suffix of the first list that matches the beginning of the second list:
A = [7,8,9]
B = [8,9,10,11,12]
C = next( A[i:] for i in range(len(A)+1) if A[i:] == B[:len(A)-i] )
# [8, 9]
Solution 3:[3]
Try this:
l1 = [1, 2, 3, 4, 4]
l2 = [3, 4, 4, 5, 6]
for i in range(len(l1)):
print(l1[i:], l2[:len(l1)-i]) # optional
if l1[i:] == l2[:len(l1)-i]: break
print(l1[i:])
Solution 4:[4]
You can start by finding the first element of b matching the last of a, then slide until the other way around is True. If you don't find the element or go beyond the max, there is no match.
def match(a, b):
try:
i = b.index(a[-1])+1
while a[-i] != b[0]:
i+=1
return b[:i]
except (ValueError, IndexError):
return []
match([7,8,8,9,9], [8,9,9,10,11,12])
# [8, 9, 9]
match([1,2,6], [4,5,6])
# []
Solution 5:[5]
You can reverse list1 and then compare the first element of list1 and list2. If they match then you save that value in a new list.
[x for x,y in zip(list2,reversed(list1) if x==y]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | phimuemue |
| Solution 2 | Alain T. |
| Solution 3 | Jacek Błocki |
| Solution 4 | mozway |
| Solution 5 | RSale |
