From bba01661ea629ff636a538226ad267a67d9dbfa7 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 18 Feb 2014 17:37:31 +0100 Subject: SI-8229 Source compatible name for implicit any2stringadd To support the established pattern for disabling it for an compilation unit. Update scaladoc's knowledge of our "typeclasses". Leave a `private[scala]` version of `StringAdd` (public in bytecode) to ensure binary compatibility with 2.11.0-M8 for partest. --- test/files/neg/logImplicits.check | 2 +- test/files/neg/predef-masking.scala | 2 +- test/files/neg/t8229.check | 4 ++++ test/files/neg/t8229.scala | 6 ++++++ test/scaladoc/run/diagrams-base.scala | 2 +- test/scaladoc/run/diagrams-filtering.scala | 2 +- 6 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 test/files/neg/t8229.check create mode 100644 test/files/neg/t8229.scala (limited to 'test') diff --git a/test/files/neg/logImplicits.check b/test/files/neg/logImplicits.check index 2265614962..270882b71a 100644 --- a/test/files/neg/logImplicits.check +++ b/test/files/neg/logImplicits.check @@ -10,7 +10,7 @@ logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert: logImplicits.scala:19: applied implicit conversion from Int(1) to ?{def ->: ?} = implicit def ArrowAssoc[A](self: A): ArrowAssoc[A] def f = (1 -> 2) + "c" ^ -logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def StringAdd[A](self: A): StringAdd[A] +logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def any2stringadd[A](self: A): any2stringadd[A] 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/predef-masking.scala b/test/files/neg/predef-masking.scala index 6f4f4859d0..67b69aa169 100644 --- a/test/files/neg/predef-masking.scala +++ b/test/files/neg/predef-masking.scala @@ -1,5 +1,5 @@ // Testing predef masking -import Predef.{ StringAdd => _, _ } +import Predef.{ any2stringadd => _, _ } object StringPlusConfusion { // Would love to do something about this error message, but by the diff --git a/test/files/neg/t8229.check b/test/files/neg/t8229.check new file mode 100644 index 0000000000..cc504fa34e --- /dev/null +++ b/test/files/neg/t8229.check @@ -0,0 +1,4 @@ +t8229.scala:5: error: value + is not a member of Object + o + "" + ^ +one error found diff --git a/test/files/neg/t8229.scala b/test/files/neg/t8229.scala new file mode 100644 index 0000000000..91966311e2 --- /dev/null +++ b/test/files/neg/t8229.scala @@ -0,0 +1,6 @@ +import Predef.{any2stringadd => _, _} + +object Test { + val o = new Object() + o + "" +} diff --git a/test/scaladoc/run/diagrams-base.scala b/test/scaladoc/run/diagrams-base.scala index b7aeed51d2..1e83a78b38 100644 --- a/test/scaladoc/run/diagrams-base.scala +++ b/test/scaladoc/run/diagrams-base.scala @@ -46,7 +46,7 @@ object Test extends ScaladocModelTest { val (incoming, outgoing) = diag.edges.partition(!_._1.isThisNode) assert(incoming.length == 5) - assert(outgoing.head._2.length == 4) + assert(outgoing.head._2.length == 4, s"${outgoing.head._2} has length ${outgoing.head._2.length}, expecting 4") val (outgoingSuperclass, outgoingImplicit) = outgoing.head._2.partition(_.isNormalNode) assert(outgoingSuperclass.length == 3) diff --git a/test/scaladoc/run/diagrams-filtering.scala b/test/scaladoc/run/diagrams-filtering.scala index 54e3e9ac63..12b5f4caba 100644 --- a/test/scaladoc/run/diagrams-filtering.scala +++ b/test/scaladoc/run/diagrams-filtering.scala @@ -57,7 +57,7 @@ object Test extends ScaladocModelTest { // Assert we have just 3 nodes and 2 edges val A = base._trait("A") val ADiag = A.inheritanceDiagram.get - assert(ADiag.nodes.length == 3) + assert(ADiag.nodes.length == 3, s"${ADiag.nodes} has length ${ADiag.nodes.length}, expected 3") assert(ADiag.edges.map(_._2.length).sum == 2) // trait C -- cgit v1.2.3 From 4223bc2ddc497457c7dccd1b9b65e98244a9b4d1 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 18 Feb 2014 11:12:50 -0800 Subject: SI-7788 Avoid accidental shadowing of Predef.conforms Rename `conforms` to `$conforms` and put in a minimal backstop: pos/t7788.scala TODO: predicate the backwards compatibility shim for `Predef_conforms` on `-Xsource:2.10` --- src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 2 +- src/library/scala/Predef.scala | 10 +++++++--- src/reflect/scala/reflect/internal/Definitions.scala | 3 ++- src/reflect/scala/reflect/internal/StdNames.scala | 2 +- test/files/pos/t7788.scala | 8 ++++++++ 5 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 test/files/pos/t7788.scala (limited to 'test') diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 8f5778862d..42687fa7b1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -807,7 +807,7 @@ trait Implicits { private def isIneligible(info: ImplicitInfo) = ( info.isCyclicOrErroneous - || isView && (info.sym eq Predef_conforms) + || isView && (info.sym eq Predef_conforms) // as an implicit conversion, Predef.$conforms is a no-op, so exclude it || (!context.macrosEnabled && info.sym.isTermMacro) ) diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 2bde6795e0..faeb1dcbe2 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -382,9 +382,13 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { @implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.") sealed abstract class <:<[-From, +To] extends (From => To) with Serializable private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x } - // not in the <:< companion object because it is also - // intended to subsume identity (which is no longer implicit) - implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A] + // The dollar prefix is to dodge accidental shadowing of this method + // by a user-defined method of the same name (SI-7788). + // The collections rely on this method. + implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A] + + @deprecated("Use `implicitly[T <:< U]` or `identity` instead.", "2.11.0") + def conforms[A]: A <:< A = $conforms[A] /** An instance of `A =:= B` witnesses that the types `A` and `B` are equal. * diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 645d6aa4ff..73f344345b 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1429,7 +1429,8 @@ trait Definitions extends api.StandardDefinitions { TypeTagClass -> materializeTypeTag ) lazy val TagSymbols = TagMaterializers.keySet - lazy val Predef_conforms = getMemberMethod(PredefModule, nme.conforms) + lazy val Predef_conforms = (getMemberIfDefined(PredefModule, nme.conforms) + orElse getMemberMethod(PredefModule, "conforms": TermName)) // TODO: predicate on -Xsource:2.10 (for now, needed for transition from M8 -> RC1) lazy val Predef_classOf = getMemberMethod(PredefModule, nme.classOf) lazy val Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly) lazy val Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray) diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index aad5f32b5f..92245790cf 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -661,7 +661,7 @@ trait StdNames { val classOf: NameType = "classOf" val clone_ : NameType = "clone" val collection: NameType = "collection" - val conforms: NameType = "conforms" + val conforms: NameType = "$conforms" // dollar prefix to avoid accidental shadowing val copy: NameType = "copy" val create: NameType = "create" val currentMirror: NameType = "currentMirror" diff --git a/test/files/pos/t7788.scala b/test/files/pos/t7788.scala new file mode 100644 index 0000000000..81eada962b --- /dev/null +++ b/test/files/pos/t7788.scala @@ -0,0 +1,8 @@ +class Test { + // Predef used to define a method `conforms` to produce the implicit evidence below + // all this does is ensure we don't rename Predef.$conforms back to conforms when $ goes out of fashion + // or that there is some other way of generating the implicit value that witnesses T => U for T <: U + def conforms(x: Int, y: Int) = x < y + def foo[A](implicit ev: Int => A) = ??? + foo[Int] +} \ No newline at end of file -- cgit v1.2.3