Getting rid of covariance would generally be, of course, unreasonable and not allowed. Given m: Map[A, String] and v : Any , you can do val mm : Map[A, Any] = m + v . This is indicated by the definition of Map , and all developers should follow. Your class may be invariant, but it must implement the full covariant Map interface.
Now redefining + to throw an error is a completely different story (not very good yet). The problem with your new + method is that after erasing the generics, it has the same signature as the other + method. There is a trick: add an implicit parameter, so that you have two parameters in the signature, which distinguishes it from the first.
def +(kv : (A,B))(implicit useless: A <:< A) : MyMap[A,B]
(it doesn't really matter what implicit parameter you are looking for if it is found. implicit useless: Ordering[String] works just as well)
By doing this, you have the usual overload problem. If you add B without a compiler, knowing that it is, the reject method is called. It might be better to do a type check there so that the B instances are accepted. This will require a manifesto [B] on your card.
source share