The former was just a straight bug; on review of the code, they had no expectation that is ought to have worked in the first place.
But the Scalaz case was actually more interesting, and you could argue that its a regression.
Consider:
class C {
private def foo: Any = 0
this match {
case d: D =>
d.foo // foo is not a member
// Would be okay:
//
// d.asInstanceOf[C with D].foo
// (d: C).foo
}
}
class D extends C
Here, we'd usually infer the type of `d` to have an intersection of the scrutinee type and the typed pattern type. But `infer.
intersect(typeOf[C], typeOf[D])` eliminates the `C`. But while it is redundant on account of subtyping, it isn't redundant when it comes to private methods.
So `intersect` is actually too eager to eliminate redundancies. If the inferred type is going to be used in a place that has private access, to a class, it should not be eliminated. I prototyped this, and it doesn't seem
too hard to implement.
An alternative would by to just never eliminate redundancies. But there would be an efficiency argument against that, as well as likely leaks into error messages.
I have a feeling that this might pop up in the wild a bit.
Should we pursue this smart intersect? If so, when? If we want to leave if out of 2.11.0, could it hit 2.11.1? (Maybe: I think we can reason that it doesn't change erasure)
I'll raise a ticket for this after discussion.
-jason