From 01f6ed8e22d02811fe62b9183d9f84bdda5ede4b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 3 May 2012 23:11:05 -0700 Subject: Fix for one of the oldest open soundness bugs. Closes SI-963, since it was one of my random 30 it won the prize. The trick after adding the stability check (which has been sitting there commented out for 3+ years) was that implicit search depended on the wrongness, because memberWildcardType would create scopes with members of the form ?{ val name: tp } And since a def shouldn't match that, fixing it broke everything until I flipped it around: memberWildcardType should be seeking ?{ def name: tp } It could also search for a mutable value: the relevant quality is that it not be stable so it doesn't have a tighter type than the members it hopes to match. --- test/files/buildmanager/t2556_3/t2556_3.check | 4 ++-- test/files/neg/logImplicits.check | 8 ++++---- test/files/neg/t963.check | 12 ++++++++++++ test/files/neg/t963.scala | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 test/files/neg/t963.check create mode 100644 test/files/neg/t963.scala (limited to 'test/files') diff --git a/test/files/buildmanager/t2556_3/t2556_3.check b/test/files/buildmanager/t2556_3/t2556_3.check index 37808d2b31..34f90f7f9b 100644 --- a/test/files/buildmanager/t2556_3/t2556_3.check +++ b/test/files/buildmanager/t2556_3/t2556_3.check @@ -9,10 +9,10 @@ invalidate B.scala because it references invalid (no longer inherited) definitio compiling Set(B.scala, C.scala) B.scala:3: error: type mismatch; found : C - required: ?{val x: ?} + required: ?{def x: ?} Note that implicit conversions are not applicable because they are ambiguous: both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] - are possible conversion functions from C to ?{val x: ?} + are possible conversion functions from C to ?{def x: ?} println( (new C).x ) ^ diff --git a/test/files/neg/logImplicits.check b/test/files/neg/logImplicits.check index d98422dacb..54afc6f86d 100644 --- a/test/files/neg/logImplicits.check +++ b/test/files/neg/logImplicits.check @@ -1,16 +1,16 @@ -logImplicits.scala:2: applied implicit conversion from xs.type to ?{val size: ?} = implicit def byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps[Byte] +logImplicits.scala:2: applied implicit conversion from xs.type to ?{def size: ?} = implicit def byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps[Byte] def f(xs: Array[Byte]) = xs.size ^ -logImplicits.scala:7: applied implicit conversion from String("abc") to ?{val map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps +logImplicits.scala:7: applied implicit conversion from String("abc") to ?{def map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps def f = "abc" map (_ + 1) ^ logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert:(p: String("abc"))Int math.max(122, x: Int) ^ -logImplicits.scala:19: applied implicit conversion from Int(1) to ?{val ->: ?} = implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] +logImplicits.scala:19: applied implicit conversion from Int(1) to ?{def ->: ?} = implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] def f = (1 -> 2) + "c" ^ -logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{val +: ?} = implicit def any2stringadd(x: Any): scala.runtime.StringAdd +logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def any2stringadd(x: Any): scala.runtime.StringAdd def f = (1 -> 2) + "c" ^ logImplicits.scala:22: error: class Un needs to be abstract, since method unimplemented is not defined diff --git a/test/files/neg/t963.check b/test/files/neg/t963.check new file mode 100644 index 0000000000..1f2d0687b3 --- /dev/null +++ b/test/files/neg/t963.check @@ -0,0 +1,12 @@ +t963.scala:14: error: stable identifier required, but Test.this.y3.x found. + val w3 : y3.x.type = y3.x + ^ +t963.scala:17: error: stable identifier required, but Test.this.y4.x found. + val w4 : y4.x.type = y4.x + ^ +t963.scala:10: error: type mismatch; + found : Object{def x: Integer} + required: AnyRef{val x: Integer} + val y2 : { val x : java.lang.Integer } = new { def x = new java.lang.Integer(r.nextInt) } + ^ +three errors found diff --git a/test/files/neg/t963.scala b/test/files/neg/t963.scala new file mode 100644 index 0000000000..0cc2034299 --- /dev/null +++ b/test/files/neg/t963.scala @@ -0,0 +1,18 @@ +import scala.util.Random + +// Only y1 (val/val) should actually compile. +object Test { + val r = new Random() + + val y1 : { val x : java.lang.Integer } = new { val x = new java.lang.Integer(r.nextInt) } + val w1 : y1.x.type = y1.x + + val y2 : { val x : java.lang.Integer } = new { def x = new java.lang.Integer(r.nextInt) } + val w2 : y2.x.type = y2.x + + val y3 : { def x : java.lang.Integer } = new { val x = new java.lang.Integer(r.nextInt) } + val w3 : y3.x.type = y3.x + + val y4 : { def x : java.lang.Integer } = new { def x = new java.lang.Integer(r.nextInt) } + val w4 : y4.x.type = y4.x +} -- cgit v1.2.3