Attempted to resolve the improbable mess surrounding

implicit conversions from Unit.  Modified test case which
relied on the supposedly verboten behavior; verbotenized
() => AnyRef; added new test case which fails if verboten
behavior should ever return.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@18079 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2009-06-22 20:26:34 +00:00
parent d26f634bfb
commit 41b93f72d1
7 changed files with 31 additions and 26 deletions

View File

@ -100,20 +100,14 @@ object Ordering
{
def apply[T](implicit ord : Ordering[T]) = ord
def ordered[A <: Ordered[A]] : Ordering[A] = new Ordering[A]{
def ordered[A <: Ordered[A]] : Ordering[A] = new Ordering[A] {
def compare(x : A, y : A) = x.compare(y);
}
trait UnitOrdering extends Ordering[Unit] {
def compare(x : Unit, y : Unit) = 0;
}
// XXX For the time being this is non-implicit so there remains
// only one default implicit conversion Unit => AnyRef (the other
// being any2stringadd in Predef.) See
// test/files/neg/structural.scala
// for an example of code which is influenced by the next line.
// implicit object Unit extends UnitOrdering
object Unit extends UnitOrdering
implicit object Unit extends UnitOrdering
trait BooleanOrdering extends Ordering[Boolean] {
def compare(x : Boolean, y : Boolean) = (x, y) match {

View File

@ -189,9 +189,8 @@ object Predef {
implicit def longWrapper(x: Long) = new runtime.RichLong(x)
implicit def floatWrapper(x: Float) = new runtime.RichFloat(x)
implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x)
implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)
implicit def unitWrapper(x: Boolean) = new runtime.RichUnit
implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)
implicit def stringWrapper(x: String) = new runtime.RichString(x)
@ -202,12 +201,6 @@ object Predef {
/** Lens from Ordering[T] to Ordered[T] */
implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] =
new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) }
/** Temporarily leaving this conversion to Ordered - see Ordering.scala for reasoning */
implicit def unit2ordered(x: Unit): Ordered[Unit] = new Ordered[Unit] with Proxy {
def self: Any = x
def compare(y: Unit): Int = 0
}
implicit def byte2short(x: Byte): Short = x.toShort
implicit def byte2int(x: Byte): Int = x.toInt

View File

@ -6,13 +6,18 @@
** |/ **
\* */
// $Id: RichInt.scala 14532 2008-04-07 12:23:22Z washburn $
// $Id: RichUnit.scala 14532 2008-04-07 12:23:22Z washburn $
package scala.runtime
/** This class exists only as a dummy subclass so that there are two ambiguous
* implicit conversions from Unit to some subclass to Object.
* It's important that this class should NOT inherit from Ordered
* It's important that this class should NOT inherit from Ordered.
*
* Note - in reality the ambiguity is successfully introduced by any2stringadd
* and orderingToOrdered, and adding an implicit from () => RichUnit actually
* resolves the ambiguity by being more specific, and succeeds! So this class
* is probably useless, and unitWrapper has been removed from Predef.
*/
final class RichUnit {}
final class RichUnit {}

View File

@ -2,7 +2,7 @@ structural.scala:3: error: illegal dependent method type
def f(x: { type D; def m: D }) = x.m
^
structural.scala:19: error: illegal dependent method type
def f9[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): D }) = x.m[Tata](()) //suceed
def f9[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): D }) = x.m[Tata](new AnyRef) //suceed
^
structural.scala:10: error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement
def f1[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: A): AnyRef; val x: A }) = x.m[Tata](x.x) //fail

View File

@ -13,11 +13,11 @@ object Test extends Application {
def f4[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: D): AnyRef; val x: D }) = x.m[Tata](x.x) //suceed
def f5[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: E): AnyRef; val x: Tata }) = x.m[Tata](x.x) //suceed
def f6[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): A }) = x.m[Tata](()) //suceed
def f7[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): B }) = x.m[Tata](()) //suceed
def f8[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): C }) = x.m[Tata](()) //suceed
def f9[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): D }) = x.m[Tata](()) //suceed
def f0[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): E }) = x.m[Tata](()) //suceed
def f6[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): A }) = x.m[Tata](new AnyRef) //suceed
def f7[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): B }) = x.m[Tata](new AnyRef) //suceed
def f8[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): C }) = x.m[Tata](new AnyRef) //suceed
def f9[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): D }) = x.m[Tata](new AnyRef) //suceed
def f0[C <: AnyRef](x: AnyRef{ type D <: AnyRef; def m[E >: Null <: AnyRef](x: AnyRef): E }) = x.m[Tata](new AnyRef) //suceed
}

View File

@ -0,0 +1,10 @@
unit2anyref.scala:2: error: type mismatch;
found : Unit
required: AnyRef
Note that implicit conversions are not applicable because they are ambiguous:
both method orderingToOrdered in object Predef of type [T](x: T)(implicit ord: Ordering[T])Ordered[T]
and method any2stringadd in object Predef of type (x: Any)scala.runtime.StringAdd
are possible conversion functions from Unit to AnyRef
val x: AnyRef = () // this should not succeed.
^
one error found

View File

@ -0,0 +1,3 @@
object Test {
val x: AnyRef = () // this should not succeed.
}