-unchecked and M7

73 views
Skip to first unread message

Mark Harrah

unread,
Aug 25, 2012, 8:39:52 AM8/25/12
to scala-i...@googlegroups.com
I haven't previously enabled -unchecked because it generated too many spurious warnings. It seems that in order to make -unchecked on by default for M7, most of these were eliminated. I only see one or two types of spurious warnings now. However, one of those types of warnings occurs frequently for me:

sealed trait A[T]
final class B[T] extends A[T]

object ParsedAxis {
def x(a: A[Int]) =
a match {
case b: B[Int] => 3
}
}

A.scala:7: non-variable type argument Int in type pattern B[Int] is unchecked since it is eliminated by erasure
case b: B[Int] => 3
^

In this case, the warning can be resolved by using a type variable:

case b: B[i] => 3

but this is less useful when reading the code and isn't possible when B[Int] is inside a type alias like 'type BI = B[Int]'. Similarly, Int @unchecked can be used, but it is less safe than the type variable approach, where the compiler still knows that i=Int is the only possibility. In fact, if another type argument is used, the compiler complains:

pattern type is incompatible with expected type;
found : B[String]
required: A[Int]
case b: B[String] => 3
^

This appears to be the underlying problem of https://issues.scala-lang.org/browse/SI-6275.

-Mark

Paul Phillips

unread,
Sep 1, 2012, 8:44:48 PM9/1/12
to scala-i...@googlegroups.com


On Saturday, August 25, 2012, Mark Harrah wrote:
I haven't previously enabled -unchecked because it generated too many spurious warnings.  It seems that in order to make -unchecked on by default for M7, most of these were eliminated.  I only see one or two types of spurious warnings now.  However, one of those types of warnings occurs frequently for me:

I will fix this.
 

Paul Phillips

unread,
Sep 24, 2012, 10:38:13 PM9/24/12
to scala-i...@googlegroups.com


On Sat, Aug 25, 2012 at 5:39 AM, Mark Harrah <dmha...@gmail.com> wrote:
I haven't previously enabled -unchecked because it generated too many spurious warnings.  It seems that in order to make -unchecked on by default for M7, most of these were eliminated.  I only see one or two types of spurious warnings now.  However, one of those types of warnings occurs frequently for me:

Try it now.

The backstory is kind of interesting; this required an unusually large amount of actual thinking (in part because the obvious approach of taking the intersection type didn't have the right behavior, so I had to invent a mechanism.) If there's some existing way to derive the information I needed, I don't know what it is, but this was a useful exercise regardless.
    
    /** On pattern matcher checkability:
     *
     *  Consider a pattern match of this form: (x: X) match { case _: P => }
     *
     *  There are four possibilities to consider:
     *     [P1] X will always conform to P
     *     [P2] x will never conform to P
     *     [P3] X <: P if some runtime test is true
     *     [P4] X cannot be checked against P
     *
     *  The first two cases correspond to those when there is enough static
     *  information to say X <: P or that !(X <: P) for all X and P.
     *  The fourth case includes unknown abstract types or structural
     *  refinements appearing within a pattern.
     *
     *  The third case is the interesting one.  We designate another type, XR,
     *  which is essentially the intersection of X and |P|, where |P| is
     *  the erasure of P.  If XR <: P, then no warning is emitted.
     *
     *  Examples of how this info is put to use:
     *  sealed trait A[T] ; class B[T] extends A[T]
     *    def f(x: B[Int]) = x match { case _: A[Int] if true => }
     *    def g(x: A[Int]) = x match { case _: B[Int] => }
     *
     *  `f` requires no warning because X=B[Int], P=A[Int], and B[Int] <:< A[Int].
     *  `g` requires no warning because X=A[Int], P=B[Int], XR=B[Int], and B[Int] <:< B[Int].
     *      XR=B[Int] because a value of type A[Int] which is tested to be a B can
     *      only be a B[Int], due to the definition of B (B[T] extends A[T].)
     *
     *  This is something like asSeenFrom, only rather than asking what a type looks
     *  like from the point of view of one of its base classes, we ask what it looks
     *  like from the point of view of one of its subclasses.
     */

Reply all
Reply to author
Forward
0 new messages