From c22ebf74e0ec17d18bf097c1d47426bd647010a5 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 22 Jun 2009 20:26:34 +0000 Subject: Attempted to resolve the improbable mess surrou... 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. --- src/library/scala/Ordering.scala | 10 ++-------- src/library/scala/Predef.scala | 9 +-------- src/library/scala/runtime/RichUnit.scala | 11 ++++++++--- test/files/neg/structural.check | 2 +- test/files/neg/structural.scala | 10 +++++----- test/files/neg/unit2anyref.check | 10 ++++++++++ test/files/neg/unit2anyref.scala | 3 +++ 7 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 test/files/neg/unit2anyref.check create mode 100644 test/files/neg/unit2anyref.scala diff --git a/src/library/scala/Ordering.scala b/src/library/scala/Ordering.scala index c772e0d3fe..38f9ffa9b4 100644 --- a/src/library/scala/Ordering.scala +++ b/src/library/scala/Ordering.scala @@ -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 { diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 49af94b716..565aa363e8 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -190,8 +190,7 @@ object Predef { 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) @@ -203,12 +202,6 @@ object Predef { 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 implicit def byte2long(x: Byte): Long = x.toLong diff --git a/src/library/scala/runtime/RichUnit.scala b/src/library/scala/runtime/RichUnit.scala index 7738d0634a..4072e81dc7 100644 --- a/src/library/scala/runtime/RichUnit.scala +++ b/src/library/scala/runtime/RichUnit.scala @@ -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 {} \ No newline at end of file diff --git a/test/files/neg/structural.check b/test/files/neg/structural.check index 3a4a627b26..cc2b5c5920 100644 --- a/test/files/neg/structural.check +++ b/test/files/neg/structural.check @@ -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 diff --git a/test/files/neg/structural.scala b/test/files/neg/structural.scala index cf75de9322..ae15c4b166 100644 --- a/test/files/neg/structural.scala +++ b/test/files/neg/structural.scala @@ -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 } diff --git a/test/files/neg/unit2anyref.check b/test/files/neg/unit2anyref.check new file mode 100644 index 0000000000..6459949341 --- /dev/null +++ b/test/files/neg/unit2anyref.check @@ -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 diff --git a/test/files/neg/unit2anyref.scala b/test/files/neg/unit2anyref.scala new file mode 100644 index 0000000000..3f5c2d19a9 --- /dev/null +++ b/test/files/neg/unit2anyref.scala @@ -0,0 +1,3 @@ +object Test { + val x: AnyRef = () // this should not succeed. +} \ No newline at end of file -- cgit v1.2.3