Skip to content

Commit

Permalink
codifies the state of the art wrt SI-8104
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
xeno-by committed Dec 28, 2013
1 parent 9f0594c commit 4b9e8e3
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 0 deletions.
4 changes: 4 additions & 0 deletions 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
11 changes: 11 additions & 0 deletions 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 }"
}
}
21 changes: 21 additions & 0 deletions 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(<type of materializeGeneric>) 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)]]
}
1 change: 1 addition & 0 deletions test/files/run/t8104.check
@@ -0,0 +1 @@
TypeTag[(Int, Int)]
11 changes: 11 additions & 0 deletions 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 }"
}
}
16 changes: 16 additions & 0 deletions 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)]]
}

0 comments on commit 4b9e8e3

Please sign in to comment.