diff options
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/neg/delayed-init-ref.check | 12 | ||||
-rw-r--r-- | test/files/neg/delayed-init-ref.flags | 1 | ||||
-rw-r--r-- | test/files/neg/delayed-init-ref.scala | 42 | ||||
-rw-r--r-- | test/files/neg/t414.check | 2 | ||||
-rw-r--r-- | test/files/neg/t4879.check | 4 | ||||
-rw-r--r-- | test/files/neg/t5663-badwarneq.check | 34 | ||||
-rw-r--r-- | test/files/neg/t5663-badwarneq.scala | 18 | ||||
-rw-r--r-- | test/files/neg/t7330.check | 5 | ||||
-rw-r--r-- | test/files/neg/t7330.scala | 5 | ||||
-rw-r--r-- | test/files/neg/t7369.check | 15 | ||||
-rw-r--r-- | test/files/neg/t7369.flags | 1 | ||||
-rw-r--r-- | test/files/neg/t7369.scala | 43 | ||||
-rw-r--r-- | test/files/pos/t6675.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t6675.scala | 20 | ||||
-rw-r--r-- | test/files/pos/t7200b.scala | 50 | ||||
-rw-r--r-- | test/files/pos/t7369.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t7369.scala | 37 | ||||
-rw-r--r-- | test/files/pos/xlint1.flags | 1 | ||||
-rw-r--r-- | test/files/pos/xlint1.scala | 13 | ||||
-rw-r--r-- | test/files/run/t7200.scala | 34 |
20 files changed, 328 insertions, 11 deletions
diff --git a/test/files/neg/delayed-init-ref.check b/test/files/neg/delayed-init-ref.check new file mode 100644 index 0000000000..ce5b205832 --- /dev/null +++ b/test/files/neg/delayed-init-ref.check @@ -0,0 +1,12 @@ +delayed-init-ref.scala:17: warning: Selecting value vall from object O, which extends scala.DelayedInit, is likely to yield an uninitialized value + println(O.vall) // warn + ^ +delayed-init-ref.scala:19: warning: Selecting value vall from object O, which extends scala.DelayedInit, is likely to yield an uninitialized value + println(vall) // warn + ^ +delayed-init-ref.scala:40: warning: Selecting value foo from trait UserContext, which extends scala.DelayedInit, is likely to yield an uninitialized value + println({locally(()); this}.foo) // warn (spurious, but we can't discriminate) + ^ +error: No warnings can be incurred under -Xfatal-warnings. +three warnings found +one error found diff --git a/test/files/neg/delayed-init-ref.flags b/test/files/neg/delayed-init-ref.flags new file mode 100644 index 0000000000..7949c2afa2 --- /dev/null +++ b/test/files/neg/delayed-init-ref.flags @@ -0,0 +1 @@ +-Xlint -Xfatal-warnings diff --git a/test/files/neg/delayed-init-ref.scala b/test/files/neg/delayed-init-ref.scala new file mode 100644 index 0000000000..f2aa804e28 --- /dev/null +++ b/test/files/neg/delayed-init-ref.scala @@ -0,0 +1,42 @@ +trait T { + val traitVal = "" +} + +object O extends App with T { + val vall = "" + lazy val lazyy = "" + def deff = "" + + println(vall) // no warn + new { + println(vall) // no warn + } +} + +object Client { + println(O.vall) // warn + import O.vall + println(vall) // warn + + println(O.lazyy) // no warn + println(O.deff) // no warn + println(O.traitVal) // no warn +} + +// Delayed init usage pattern from Specs2 +// See: https://groups.google.com/d/msg/scala-sips/wP6dL8nIAQs/ogjoPE-MSVAJ +trait Before extends DelayedInit { + def before() + override def delayedInit(x: => Unit): Unit = { before; x } +} +object Spec { + trait UserContext extends Before { + def before() = () + val foo = "foo" + } + new UserContext { + println(foo) // no warn + println(this.foo) // no warn + println({locally(()); this}.foo) // warn (spurious, but we can't discriminate) + } +} diff --git a/test/files/neg/t414.check b/test/files/neg/t414.check index e15dbaea71..30211eef8e 100644 --- a/test/files/neg/t414.check +++ b/test/files/neg/t414.check @@ -1,7 +1,7 @@ t414.scala:5: error: pattern type is incompatible with expected type; found : Empty.type required: IntMap[a] -Note: if you intended to match against the class, try `case _: Empty[_]` or `case Empty()` +Note: if you intended to match against the class, try `case Empty()` case Empty => ^ t414.scala:7: error: type mismatch; diff --git a/test/files/neg/t4879.check b/test/files/neg/t4879.check index 21cd329640..c7edd583c8 100644 --- a/test/files/neg/t4879.check +++ b/test/files/neg/t4879.check @@ -1,13 +1,13 @@ t4879.scala:6: error: pattern type is incompatible with expected type; found : C.type required: C -Note: if you intended to match against the class, try `case _: C` or `case C(_)` +Note: if you intended to match against the class, try `case C(_)` case C => true ^ t4879.scala:10: error: pattern type is incompatible with expected type; found : D.type required: D[T,U,V] -Note: if you intended to match against the class, try `case _: D[_,_,_]` or `case D(_,_,_)` +Note: if you intended to match against the class, try `case D(_,_,_)` case D => true ^ two errors found diff --git a/test/files/neg/t5663-badwarneq.check b/test/files/neg/t5663-badwarneq.check index 12e93ff373..732e4f44d0 100644 --- a/test/files/neg/t5663-badwarneq.check +++ b/test/files/neg/t5663-badwarneq.check @@ -1,24 +1,42 @@ -t5663-badwarneq.scala:42: warning: comparing case class values of types Some[Int] and None.type using `==' will always yield false +t5663-badwarneq.scala:47: warning: comparing case class values of types Some[Int] and None.type using `==' will always yield false println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object ^ -t5663-badwarneq.scala:43: warning: comparing case class values of types Some[Int] and Thing using `==' will always yield false +t5663-badwarneq.scala:48: warning: comparing case class values of types Some[Int] and Thing using `==' will always yield false println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object ^ -t5663-badwarneq.scala:51: warning: ThingOne and Thingy are unrelated: they will most likely never compare equal +t5663-badwarneq.scala:56: warning: ThingOne and Thingy are unrelated: they will most likely never compare equal println(t1 == t2) // true, but apparently unrelated, a compromise warning ^ -t5663-badwarneq.scala:52: warning: ThingThree and Thingy are unrelated: they will most likely never compare equal +t5663-badwarneq.scala:57: warning: ThingThree and Thingy are unrelated: they will most likely never compare equal println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated ^ -t5663-badwarneq.scala:55: warning: comparing case class values of types ThingTwo and Some[Int] using `==' will always yield false +t5663-badwarneq.scala:60: warning: comparing case class values of types ThingTwo and Some[Int] using `==' will always yield false println(t3 == Some(1)) // false, warn on different cases ^ -t5663-badwarneq.scala:56: warning: comparing values of types ThingOne and Cousin using `==' will always yield false +t5663-badwarneq.scala:61: warning: comparing values of types ThingOne and Cousin using `==' will always yield false println(t1 == c) // should warn ^ -t5663-badwarneq.scala:64: warning: comparing case class values of types Simple and SimpleSibling.type using `==' will always yield false +t5663-badwarneq.scala:69: warning: comparing case class values of types Simple and SimpleSibling.type using `==' will always yield false println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case ^ +t5663-badwarneq.scala:72: warning: ValueClass1 and Int are unrelated: they will never compare equal + println(new ValueClass1(5) == 5) // bad + ^ +t5663-badwarneq.scala:74: warning: comparing values of types Int and ValueClass1 using `==' will always yield false + println(5 == new ValueClass1(5)) // bad + ^ +t5663-badwarneq.scala:78: warning: ValueClass2[String] and String are unrelated: they will never compare equal + println(new ValueClass2("abc") == "abc") // bad + ^ +t5663-badwarneq.scala:79: warning: ValueClass2[Int] and ValueClass1 are unrelated: they will never compare equal + println(new ValueClass2(5) == new ValueClass1(5)) // bad - different value classes + ^ +t5663-badwarneq.scala:81: warning: comparing values of types ValueClass3 and ValueClass2[Int] using `==' will always yield false + println(ValueClass3(5) == new ValueClass2(5)) // bad + ^ +t5663-badwarneq.scala:82: warning: comparing values of types ValueClass3 and Int using `==' will always yield false + println(ValueClass3(5) == 5) // bad + ^ error: No warnings can be incurred under -Xfatal-warnings. -7 warnings found +13 warnings found one error found diff --git a/test/files/neg/t5663-badwarneq.scala b/test/files/neg/t5663-badwarneq.scala index 56ec389c03..3c0376914e 100644 --- a/test/files/neg/t5663-badwarneq.scala +++ b/test/files/neg/t5663-badwarneq.scala @@ -17,6 +17,11 @@ class SimpleParent case class Simple() extends SimpleParent case object SimpleSibling extends SimpleParent +// value classes +final class ValueClass1(val value: Int) extends AnyVal +final class ValueClass2[T](val value: T) extends AnyVal +final case class ValueClass3(val value: Int) extends AnyVal + /* It's not possible to run partest without -deprecation. * Since detecting the warnings requires a neg test with * -Xfatal-warnings, and deprecation terminates the compile, @@ -63,6 +68,19 @@ object Test { println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case + println(new ValueClass1(5) == new ValueClass1(5)) // ok + println(new ValueClass1(5) == 5) // bad + println(new ValueClass1(5) == (5: Any)) // ok, have to let it through + println(5 == new ValueClass1(5)) // bad + println((5: Any) == new ValueClass1(5) == (5: Any)) // ok + + println(new ValueClass2("abc") == new ValueClass2("abc")) // ok + println(new ValueClass2("abc") == "abc") // bad + println(new ValueClass2(5) == new ValueClass1(5)) // bad - different value classes + println(ValueClass3(5) == new ValueClass3(5)) // ok + println(ValueClass3(5) == new ValueClass2(5)) // bad + println(ValueClass3(5) == 5) // bad + /* val mine = new MyThing val some = new SomeThing diff --git a/test/files/neg/t7330.check b/test/files/neg/t7330.check new file mode 100644 index 0000000000..b96d656d2b --- /dev/null +++ b/test/files/neg/t7330.check @@ -0,0 +1,5 @@ +t7330.scala:4: error: pattern must be a value: Y[_] +Note: if you intended to match against the class, try `case _: Y[_]` + 0 match { case Y[_] => } + ^ +one error found diff --git a/test/files/neg/t7330.scala b/test/files/neg/t7330.scala new file mode 100644 index 0000000000..13a943a02b --- /dev/null +++ b/test/files/neg/t7330.scala @@ -0,0 +1,5 @@ +class Y[T] +class Test { + // TypeTree is not a valid tree for a pattern + 0 match { case Y[_] => } +}
\ No newline at end of file diff --git a/test/files/neg/t7369.check b/test/files/neg/t7369.check new file mode 100644 index 0000000000..a4e99f496e --- /dev/null +++ b/test/files/neg/t7369.check @@ -0,0 +1,15 @@ +t7369.scala:6: warning: unreachable code + case Tuple1(X) => // unreachable + ^ +t7369.scala:13: warning: unreachable code + case Tuple1(true) => // unreachable + ^ +t7369.scala:31: warning: unreachable code + case Tuple1(X) => // unreachable + ^ +t7369.scala:40: warning: unreachable code + case Tuple1(null) => // unreachable + ^ +error: No warnings can be incurred under -Xfatal-warnings. +four warnings found +one error found diff --git a/test/files/neg/t7369.flags b/test/files/neg/t7369.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/t7369.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/neg/t7369.scala b/test/files/neg/t7369.scala new file mode 100644 index 0000000000..87ddfe98b7 --- /dev/null +++ b/test/files/neg/t7369.scala @@ -0,0 +1,43 @@ +object Test { + val X, Y = true + (null: Tuple1[Boolean]) match { + case Tuple1(X) => + case Tuple1(Y) => + case Tuple1(X) => // unreachable + case _ => + } + + (null: Tuple1[Boolean]) match { + case Tuple1(true) => + case Tuple1(false) => + case Tuple1(true) => // unreachable + case _ => + } +} + + +sealed abstract class B; +case object True extends B; +case object False extends B; + +object Test2 { + + val X: B = True + val Y: B = False + + (null: Tuple1[B]) match { + case Tuple1(X) => + case Tuple1(Y) => + case Tuple1(X) => // unreachable + case _ => + } +} + +object Test3 { + (null: Tuple1[B]) match { + case Tuple1(null) => + case Tuple1(True) => + case Tuple1(null) => // unreachable + case _ => + } +} diff --git a/test/files/pos/t6675.flags b/test/files/pos/t6675.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t6675.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t6675.scala b/test/files/pos/t6675.scala new file mode 100644 index 0000000000..f3bebea5be --- /dev/null +++ b/test/files/pos/t6675.scala @@ -0,0 +1,20 @@ +object LeftOrRight { + def unapply[A](value: Either[A, A]): Option[A] = value match { + case scala.Left(x) => Some(x) + case scala.Right(x) => Some(x) + } +} + +object Test { + (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { + case LeftOrRight(pair @ (a, b)) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)" + } + + (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { + case LeftOrRight((a, b)) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)" + } + + (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { + case LeftOrRight(a, b) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)" + } +} diff --git a/test/files/pos/t7200b.scala b/test/files/pos/t7200b.scala new file mode 100644 index 0000000000..9d579c6ef9 --- /dev/null +++ b/test/files/pos/t7200b.scala @@ -0,0 +1,50 @@ +import language.higherKinds + +trait T { + def t = 0 +} +trait Foo { + def coflatMap[A <: T](f: A): A +} + +object O extends Foo { + def coflatMap[A <: T](f: A) = { + val f2 = coflatMap(f) // inferred in 2.9.2 / 2.10.0 as [Nothing] + f2.t // so this does't type check. + f2 + } +} + +// Why? When a return type is inherited, the derived method +// symbol first gets a preliminary type assigned, based on the +// 1) method type of a unique matching super member +// 2) viewed as a member type of the inheritor (to substitute, +// e.g. class type parameters) +// 3) substituted to replace the super-method's type parameters +// with those of the inheritor +// 4) dissected to take just the return type wrapped in thisMethodType(). +// +// In Scala 2.10.0 and earlier, this preliminary method type +// +// 1) [A#11329 <: <empty>#3.this.T#7068](<param> f#11333: A#11329)A#11329 +// 2) [A#11329 <: <empty>#3.this.T#7068](<param> f#11333: A#11329)A#11329 +// 3) (<param> f#12556: A#11336)A#11336 +// 4) [A#11336 <: <empty>#3.this.T#7068](<param> f#12552: A#11337&0)A#11336 +// +// The type #4 from the old version is problematic: the parameter is typed with +// a skolem for the type parameter `A`. It won't be considered to match the +// method it overrides, instead they are seen as being overloaded, and type inference +// goes awry (Nothing is inferred as the type argument for the recursive call +// to coflatMap. +// +// The Namers patch adds one step here: it subsitutes the type parameter symbols +// for the skolems: +// +// https://github.com/scala/scala/commit/b74c33eb#L2R1014 +// +// So we end up with a method symbol info: +// +// 5) [A#11336 <: <empty>#3.this.T#7068](<param> f#12505: A#11336)A#11336 +// +// This *does* match the method in the super class, and type inference +// chooses the correct type argument.
\ No newline at end of file diff --git a/test/files/pos/t7369.flags b/test/files/pos/t7369.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/pos/t7369.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/pos/t7369.scala b/test/files/pos/t7369.scala new file mode 100644 index 0000000000..2f31c93d29 --- /dev/null +++ b/test/files/pos/t7369.scala @@ -0,0 +1,37 @@ +object Test { + val X, Y = true + (null: Tuple1[Boolean]) match { + case Tuple1(X) => + case Tuple1(Y) => // unreachable + case _ => + } +} + + +sealed abstract class B; +case object True extends B; +case object False extends B; + +object Test2 { + + val X: B = True + val Y: B = False + + (null: Tuple1[B]) match { + case Tuple1(X) => + case Tuple1(Y) => // no warning + case _ => + } +} + +object Test3 { + val X, O = true + def classify(neighbourhood: (Boolean, Boolean, Boolean)): String = { + neighbourhood match { + case (X, X, X) => "middle" + case (X, X, O) => "right" + case (O, X, X) => "left" + case _ => throw new IllegalArgumentException("Invalid") + } + } +}
\ No newline at end of file diff --git a/test/files/pos/xlint1.flags b/test/files/pos/xlint1.flags new file mode 100644 index 0000000000..7949c2afa2 --- /dev/null +++ b/test/files/pos/xlint1.flags @@ -0,0 +1 @@ +-Xlint -Xfatal-warnings diff --git a/test/files/pos/xlint1.scala b/test/files/pos/xlint1.scala new file mode 100644 index 0000000000..27936d8b14 --- /dev/null +++ b/test/files/pos/xlint1.scala @@ -0,0 +1,13 @@ +package object foo { + implicit class Bar[T](val x: T) extends AnyVal { + def bippy = 1 + } +} + +package foo { + object Baz { + def main(args: Array[String]): Unit = { + "abc".bippy + } + } +} diff --git a/test/files/run/t7200.scala b/test/files/run/t7200.scala new file mode 100644 index 0000000000..ba342df14d --- /dev/null +++ b/test/files/run/t7200.scala @@ -0,0 +1,34 @@ +import language.higherKinds + +object Test extends App { + + // Slice of comonad is where this came up + trait Foo[F[_]] { + def coflatMap[A, B](f: F[A] => B): F[A] => F[B] + } + + // A non-empty list + case class Nel[A](head: A, tail: List[A]) + + object NelFoo extends Foo[Nel] { + + // It appears that the return type for recursive calls is not inferred + // properly, yet no warning is issued. Providing a return type or + // type arguments for the recursive call fixes the problem. + + def coflatMap[A, B](f: Nel[A] => B) = // ok w/ return type + l => Nel(f(l), l.tail match { + case Nil => Nil + case h :: t => { + val r = coflatMap(f)(Nel(h, t)) // ok w/ type args + r.head :: r.tail + } + }) + } + + // Without a recursive call all is well, but with recursion we get a + // ClassCastException from Integer to Nothing + NelFoo.coflatMap[Int, Int](_.head + 1)(Nel(1, Nil)) // Ok + NelFoo.coflatMap[Int, Int](_.head + 1)(Nel(1, List(2))) // CCE + +} |