From 4b9e8e34171e2162af2b1ce7faef45c31814a477 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 28 Dec 2013 02:40:44 +0300 Subject: codifies the state of the art wrt SI-8104 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it was discovered in SI-8104, whiteboxity doesn’t apply equally to type parameters and type members of materialized type classes. During implicit search and subsequent type inference, whitebox type parameters are consistently erased to wildcards, whereas whitebox type members sometimes remain as is and get in the way of signature conformance checks. --- test/files/neg/t8104.check | 4 ++++ test/files/neg/t8104/Macros_1.scala | 11 +++++++++++ test/files/neg/t8104/Test_2.scala | 21 +++++++++++++++++++++ test/files/run/t8104.check | 1 + test/files/run/t8104/Macros_1.scala | 11 +++++++++++ test/files/run/t8104/Test_2.scala | 16 ++++++++++++++++ 6 files changed, 64 insertions(+) create mode 100644 test/files/neg/t8104.check create mode 100644 test/files/neg/t8104/Macros_1.scala create mode 100644 test/files/neg/t8104/Test_2.scala create mode 100644 test/files/run/t8104.check create mode 100644 test/files/run/t8104/Macros_1.scala create mode 100644 test/files/run/t8104/Test_2.scala (limited to 'test') diff --git a/test/files/neg/t8104.check b/test/files/neg/t8104.check new file mode 100644 index 0000000000..69b3461bd5 --- /dev/null +++ b/test/files/neg/t8104.check @@ -0,0 +1,4 @@ +Test_2.scala:20: error: could not find implicit value for parameter e: Generic.Aux[Test.C,(Int, Int)] + implicitly[Generic.Aux[C, (Int, Int)]] + ^ +one error found diff --git a/test/files/neg/t8104/Macros_1.scala b/test/files/neg/t8104/Macros_1.scala new file mode 100644 index 0000000000..21d81a3687 --- /dev/null +++ b/test/files/neg/t8104/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.WhiteboxContext + +object Macros { + def impl[T](c: WhiteboxContext)(implicit T: c.WeakTypeTag[T]) = { + import c.universe._ + import definitions._ + val fields = T.tpe.declarations.toList.collect{ case x: TermSymbol if x.isVal && x.isCaseAccessor => x } + val Repr = appliedType(TupleClass(fields.length).asType.toType, fields.map(_.typeSignature)) + q"new Generic[$T]{ type Repr = $Repr }" + } +} \ No newline at end of file diff --git a/test/files/neg/t8104/Test_2.scala b/test/files/neg/t8104/Test_2.scala new file mode 100644 index 0000000000..585f76c00f --- /dev/null +++ b/test/files/neg/t8104/Test_2.scala @@ -0,0 +1,21 @@ +trait Generic[T] { type Repr } +object Generic { + type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 } + import scala.language.experimental.macros + implicit def materializeGeneric[T]: Generic[T] = macro Macros.impl[T] +} + +object Test extends App { + case class C(x: Int, y: Int) + + import scala.reflect.runtime.universe._ + def reprify[T, Repr](x: T)(implicit generic: Generic.Aux[T, Repr], tag: TypeTag[Repr]) = println(tag) + reprify(C(40, 2)) + + // this is a compilation error at the moment as explained in SI-8104 + // because matchesPt in implicit search says that depoly() isn't a subtype of Generic.Aux[C, (Int, Int)] + // which is rightfully so, because depoly only replaces type parameters, not type members with wildcard types + // however in the future we might want to relax the matchesPt check, so this might start compiling + // therefore, if you've broken this test, then you should be happy, because most likely you've just enabled an interesting use case! + implicitly[Generic.Aux[C, (Int, Int)]] +} diff --git a/test/files/run/t8104.check b/test/files/run/t8104.check new file mode 100644 index 0000000000..c2593eb199 --- /dev/null +++ b/test/files/run/t8104.check @@ -0,0 +1 @@ +TypeTag[(Int, Int)] diff --git a/test/files/run/t8104/Macros_1.scala b/test/files/run/t8104/Macros_1.scala new file mode 100644 index 0000000000..21d81a3687 --- /dev/null +++ b/test/files/run/t8104/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.WhiteboxContext + +object Macros { + def impl[T](c: WhiteboxContext)(implicit T: c.WeakTypeTag[T]) = { + import c.universe._ + import definitions._ + val fields = T.tpe.declarations.toList.collect{ case x: TermSymbol if x.isVal && x.isCaseAccessor => x } + val Repr = appliedType(TupleClass(fields.length).asType.toType, fields.map(_.typeSignature)) + q"new Generic[$T]{ type Repr = $Repr }" + } +} \ No newline at end of file diff --git a/test/files/run/t8104/Test_2.scala b/test/files/run/t8104/Test_2.scala new file mode 100644 index 0000000000..630176f175 --- /dev/null +++ b/test/files/run/t8104/Test_2.scala @@ -0,0 +1,16 @@ +trait Generic[T] { type Repr } +object Generic { + type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 } + import scala.language.experimental.macros + implicit def materializeGeneric[T, Repr]: Generic.Aux[T, Repr] = macro Macros.impl[T] +} + +object Test extends App { + case class C(x: Int, y: Int) + + import scala.reflect.runtime.universe._ + def reprify[T, Repr](x: T)(implicit generic: Generic.Aux[T, Repr], tag: TypeTag[Repr]) = println(tag) + reprify(C(40, 2)) + + implicitly[Generic.Aux[C, (Int, Int)]] +} -- cgit v1.2.3