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:
parent
d26f634bfb
commit
41b93f72d1
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
object Test {
|
||||
val x: AnyRef = () // this should not succeed.
|
||||
}
|
Loading…
Reference in New Issue