The following code snipped does not compile, but I think it should.
sealed trait HasSome{
type SomeType
val someVal: SomeType
}
class HasInts(i:Int) extends HasSome{
type SomeType = Int
val someVal=i
}
def getSome(v:HasSome): v.SomeType = v match{
case i: HasInts => i.someVal
}
Why is the compiler of the opinion that i.SomeType does not conform to v.SomeType? Do I miss something or is this more like a bug?
Thanks in Advance for any input!
The pattern has an explicit type ascription i: HasInts. It would be rather strange to infer a different type for i than the one that was explicitly requested by the user. I’m surprised that your version compiles, it’s probably a bug (as you noted, due to the trivial type test that can be removed).
Inside the pattern match, the compiler “loses” the information, that i is of the same type as v.
I’m not sure if this is a bug. I’d argue that the spec covers this in 8.1.2:
A typed pattern x:T consists of a pattern variable x and a type pattern T. The type of x is the type pattern T, where each type variable and wildcard is replaced by a fresh, unknown type.
So as far as I understand it, it says the pattern variable only has the type specified in the pattern. But this also means, you can change your pattern to not lose the relevant information:
def getSome(v:HasSome): v.SomeType = v match{
case i: HasInts with v.type => v.someVal
}
This way the compiler knows that i is also of v’s type and therefore i.SomeType is v.SomeType.