I’ve encountered something that feels like a bug, but might also just be one of these dark corners coming from Java and known to be better left alone because we can’t work around them.
Using Scala 3.6.2, take the following code:
enum Type:
case Num
case Bool
enum TypeRepr[A <: Type]:
case Num extends TypeRepr[Type.Num.type]
case Bool extends TypeRepr[Type.Bool.type]
override def equals(other: Any) = true
def to[A <: Type](repr: TypeRepr[A]): A = repr match
case TypeRepr.Bool => Type.Bool
case TypeRepr.Num => Type.Num
@main def run =
val nonsense: Type.Num.type = to(TypeRepr.Num)
println(nonsense)
nonsense
, of type Type.Num.type
, is in fact Type.Bool
, of an incompatible type.
My understanding of this is that the compiler trusts that if two values are equal, then they are of the same type, and reasons off of that premise. And my implementation provides an incorrect equals
, thus leading the compiler to incorrect conclusions.
Is this something known, and if so, is there a list of such corner cases somewhere? Or should I report that as a bug?
1 Like
That is a bug. There was an ancient Scala 2 ticket on this question of what type can be inferred from equality.
The correcter code is:
def to[A <: Type](repr: TypeRepr[A]): A = repr match
case _: TypeRepr.Bool.type => Type.Bool
case _: TypeRepr.Num.type => Type.Num
Your ticket has the same issue, where I would expect
case class Typing[A <: Type](expr: TypedExpr[A], tpe: A):
def cast[B <: Type](to: B): Either[String, TypedExpr[B]] = this match
case Typing(expr, _: to.type) => Right(expr)
case _ => Left("Failed")
though that doesn’t meet your expectation there.
Matching on x.type
uses eq
instead of equals
.
1 Like
You mean _: to.type
, right?
I didn’t think of using type comparisons, although that’s not always possible - sometime I actually need the value, and I need it well typed. But thanks, that’s a good workaround at least in this scenario!
I’m a little confused by the eq
comment though. Surely matching on x.type
uses asInstanceOf
and not eq
?
thanks, fixed.
https://scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#type-patterns
A singleton type pp.type
. This type pattern matches only the value denoted by the path pp (the eq
method is used to compare the matched value to pp).
And don’t call me Shirley.
Now then, Herr Snytt… at least he didn’t call you Abbie Ant Toe.
Regards, Mr Meaner.
it’s a meme, in modern parlance.
1 Like
Oh i thought I’d offended you somehow
1 Like