aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-02-01 16:43:00 +1100
committerMartin Odersky <odersky@gmail.com>2017-02-01 16:43:00 +1100
commitb11e6d678a92187e5e9f821ba1116cec2cce0f8c (patch)
tree81efac5e249e680d23c777752c98e3e649508b5d
parent2ce93287d809ed0012546c8466712a40e5a9c2e5 (diff)
downloaddotty-b11e6d678a92187e5e9f821ba1116cec2cce0f8c.tar.gz
dotty-b11e6d678a92187e5e9f821ba1116cec2cce0f8c.tar.bz2
dotty-b11e6d678a92187e5e9f821ba1116cec2cce0f8c.zip
Handle Array classtags in the same way as others
The previous implicit definition of arrayTag in DottyPredef priorities arrayTag over all other classtag searches, which led to surprising results in `i1907a.scala`.
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala47
-rw-r--r--library/src/dotty/DottyPredef.scala3
2 files changed, 28 insertions, 22 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index 183dff282..2112b1221 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -507,7 +507,34 @@ trait Implicits { self: Typer =>
* which is itself parameterized by another string,
* indicating where the implicit parameter is needed
*/
- def inferImplicitArg(formal: Type, error: (String => String) => Unit, pos: Position)(implicit ctx: Context): Tree =
+ def inferImplicitArg(formal: Type, error: (String => String) => Unit, pos: Position)(implicit ctx: Context): Tree = {
+
+ /** If `formal` is of the form ClassTag[T], where `T` is a class type,
+ * synthesize a class tag for `T`.
+ */
+ def synthesizedClassTag(formal: Type, pos: Position)(implicit ctx: Context): Tree = {
+ if (formal.isRef(defn.ClassTagClass))
+ formal.argTypes match {
+ case arg :: Nil =>
+ fullyDefinedType(arg, "ClassTag argument", pos) match {
+ case defn.ArrayOf(elemTp) =>
+ val etag = inferImplicitArg(defn.ClassTagType.appliedTo(elemTp), error, pos)
+ if (etag.isEmpty) etag else etag.select(nme.wrap)
+ case tp if hasStableErasure(tp) =>
+ ref(defn.ClassTagModule)
+ .select(nme.apply)
+ .appliedToType(tp)
+ .appliedTo(clsOf(erasure(tp)))
+ .withPos(pos)
+ case tp =>
+ EmptyTree
+ }
+ case _ =>
+ EmptyTree
+ }
+ else EmptyTree
+ }
+
inferImplicit(formal, EmptyTree, pos) match {
case SearchSuccess(arg, _, _, _) =>
arg
@@ -534,24 +561,6 @@ trait Implicits { self: Typer =>
EmptyTree
}
}
-
- /** If `formal` is of the form ClassTag[T], where `T` is a class type,
- * synthesize a class tag for `T`.
- */
- def synthesizedClassTag(formal: Type, pos: Position)(implicit ctx: Context): Tree = {
- if (formal.isRef(defn.ClassTagClass))
- formal.argTypes match {
- case arg :: Nil =>
- val tp = fullyDefinedType(arg, "ClassTag argument", pos)
- if (hasStableErasure(tp))
- return ref(defn.ClassTagModule)
- .select(nme.apply)
- .appliedToType(tp)
- .appliedTo(clsOf(erasure(tp)))
- .withPos(pos)
- case _ =>
- }
- EmptyTree
}
private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) = {
diff --git a/library/src/dotty/DottyPredef.scala b/library/src/dotty/DottyPredef.scala
index cd90c4882..c7cf2a906 100644
--- a/library/src/dotty/DottyPredef.scala
+++ b/library/src/dotty/DottyPredef.scala
@@ -9,9 +9,6 @@ import scala.collection.Seq
object DottyPredef {
implicit def typeTag[T]: TypeTag[T] = ???
- implicit def arrayTag[T](implicit ctag: ClassTag[T]): ClassTag[Array[T]] =
- ctag.wrap
-
/** A fall-back implicit to compare values of any types.
* The compiler will restrict implicit instances of `eqAny`. An instance
* `eqAny[T, U]` is _valid_ if `T <: U` or `U <: T` or both `T` and `U` are