Is Shapeless' type inequality buggy?

268 views Asked by At

Type inequality in shapeless does not seem to be safe once type parameters enter the picture.

For example the following code compiles

def someMethod[T](in : T) = {

  implicitly[T =:!= String]

  // some operation that requires T not String could be called here
  // even though there is no guarantee that this is safe
}

val a = someMethod("abc") // here we have just proven String != String

My intuition is that the correct behavior should be a compile time error (we have generated a proof that String =!:= String)

This is not related to the =:!= operator but to all situations in which implicit conflicts are used to emulate a negation operator.

Is this really a bug or am I missing an important point?

2

There are 2 answers

2
Michael Zajac On

T =:!= String needs to be an implicit argument of someMethod. We need to collect the evidence that T is not a String at the call site, otherwise it's too late. T is erased within the body of someMethod.

def someMethod[T](in : T)(implicit ev: T =:!= String) = {
  println("Definitely not a string")
}

scala> someMethod("abc")
<console>:16: error: ambiguous implicit values:
 both method neqAmbig1 in package shapeless of type [A]=> shapeless.=:!=[A,A]
 and method neqAmbig2 in package shapeless of type [A]=> shapeless.=:!=[A,A]
 match expected type shapeless.=:!=[String,String]
       someMethod("abc")
                 ^
0
Miles Sabin On

It's a bug, or at best a surprising misfeature.