Skip to content

Commit f2f1433

Browse files
committed
Fix scala#5965: Make scala.quoted.Type poly-kinded
1 parent ea6f9a1 commit f2f1433

File tree

7 files changed

+97
-6
lines changed

7 files changed

+97
-6
lines changed

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,14 @@ class ReifyQuotes extends MacroTransform {
352352
transformSplice(spliceTree)
353353

354354
case tree: TypeTree if tree.tpe.typeSymbol.isSplice =>
355-
val splicedType = tree.tpe.stripTypeVar.asInstanceOf[TypeRef].prefix.termSymbol
356-
transformSplice(ref(splicedType).select(tpnme.splice).withSpan(tree.span))
355+
tree.tpe.stripTypeVar match {
356+
case tp: AppliedType =>
357+
val splicedType = tp.tycon.asInstanceOf[TypeRef].prefix.termSymbol
358+
AppliedTypeTree(transformSplice(ref(splicedType).select(tpnme.splice)), tp.args.map(TypeTree(_))).withSpan(tree.span)
359+
case tp: TypeRef =>
360+
val splicedType = tp.prefix.termSymbol
361+
transformSplice(ref(splicedType).select(tpnme.splice).withSpan(tree.span))
362+
}
357363

358364
case tree: RefTree if isCaptured(tree.symbol, level) =>
359365
val t = capturers(tree.symbol).apply(tree)

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ object TestConfiguration {
4747
val yCheckOptions = Array("-Ycheck:all")
4848

4949
val commonOptions = checkOptions ++ noCheckOptions ++ yCheckOptions
50-
val defaultOptions = TestFlags(basicClasspath, commonOptions)
50+
val defaultOptions = TestFlags(basicClasspath, commonOptions) and "-Ykind-polymorphism" // FIXME remove "-Ykind-polymorphism"
5151
val withCompilerOptions =
5252
defaultOptions.withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath)
5353
val allowDeepSubtypes = defaultOptions without "-Yno-deep-subtypes"

library/src/scala/quoted/Type.scala renamed to library/src-bootstrapped/scala/quoted/Type.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import scala.quoted.Types.TaggedType
44
import scala.reflect.ClassTag
55
import scala.runtime.quoted.Unpickler.Pickled
66

7-
sealed abstract class Type[T] {
7+
sealed abstract class Type[T <: AnyKind] {
88
type `$splice` = T
99
}
1010

1111
/** Some basic type tags, currently incomplete */
1212
object Type {
1313
/** A term quote is desugared by the compiler into a call to this method */
14-
def apply[T]: Type[T] =
14+
def apply[T <: AnyKind]: Type[T] =
1515
throw new Error("Internal error: this method call should have been replaced by the compiler")
1616

1717
implicit def UnitTag: Type[Unit] = new TaggedType[Unit]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package scala.quoted
2+
3+
import scala.quoted.Types.TaggedType
4+
import scala.reflect.ClassTag
5+
import scala.runtime.quoted.Unpickler.Pickled
6+
7+
sealed abstract class Type[T] {
8+
type `$splice` = T
9+
}
10+
11+
/** Some basic type tags, currently incomplete */
12+
object Type {
13+
/** A term quote is desugared by the compiler into a call to this method */
14+
def apply[T]: Type[T] =
15+
throw new Error("Internal error: this method call should have been replaced by the compiler")
16+
}
17+
18+
/** All implementations of Type[T].
19+
* These should never be used directly.
20+
*/
21+
object Types {
22+
/** A Type backed by a pickled TASTY tree */
23+
final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] {
24+
override def toString(): String = s"Type(<pickled tasty>)"
25+
}
26+
27+
/** An Type backed by a value */
28+
final class TaggedType[T](implicit val ct: ClassTag[T]) extends Type[T] {
29+
override def toString: String = s"Type($ct)"
30+
}
31+
32+
/** An Type backed by a tree */
33+
final class TreeType[Tree](val typeTree: Tree) extends quoted.Type[Any] {
34+
override def toString: String = s"Type(<tasty tree>)"
35+
}
36+
}

project/Build.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,11 +1135,17 @@ object Build {
11351135
def asDottyCompiler(implicit mode: Mode): Project = project.withCommonSettings.
11361136
dependsOn(`dotty-interfaces`).
11371137
dependsOn(dottyLibrary).
1138-
settings(dottyCompilerSettings)
1138+
settings(dottyCompilerSettings).
1139+
bootstrappedSettings(
1140+
// To support kind polymorphism of scala.quote.Type
1141+
scalacOptions in Compile += "-Ykind-polymorphism"
1142+
)
11391143

11401144
def asDottyLibrary(implicit mode: Mode): Project = project.withCommonSettings.
11411145
settings(dottyLibrarySettings).
11421146
bootstrappedSettings(
1147+
// To support kind polymorphism of scala.quote.Type
1148+
scalacOptions in Compile += "-Ykind-polymorphism",
11431149
// Needed so that the library sources are visible when `dotty.tools.dotc.core.Definitions#init` is called.
11441150
scalacOptions in Compile ++= Seq("-sourcepath", (scalaSource in Compile).value.getAbsolutePath)
11451151
)

tests/run-with-compiler/i5965.check

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
val y: collection.immutable.List[scala.Int] = scala.List.apply[scala.Int](1, 2, 3)
3+
(y: collection.immutable.List[evidence$1$_~$1])
4+
}
5+
List(1, 2, 3)
6+
{
7+
val y: scala.Option[scala.Int] = scala.Option.apply[scala.Int](4)
8+
(y: scala.Option[evidence$1$_~$1])
9+
}
10+
Some(4)
11+
{
12+
val y: collection.immutable.Map[scala.Int, scala.Int] = scala.Predef.Map.apply[scala.Int, scala.Int](scala.Predef.ArrowAssoc[scala.Int](4).->[scala.Int](1))
13+
(y: collection.immutable.Map[scala.Int, evidence$1$_~$1])
14+
}
15+
Map(4 -> 1)

tests/run-with-compiler/i5965.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Test {
6+
7+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
8+
9+
def main(args: Array[String]): Unit = {
10+
'[List]
11+
val list = bound('{List(1, 2, 3)})
12+
println(list.show)
13+
println(list.run)
14+
15+
val opt = bound('{Option(4)})
16+
println(opt.show)
17+
println(opt.run)
18+
19+
val map = bound('{Map(4 -> 1)})
20+
println(map.show)
21+
println(map.run)
22+
}
23+
24+
def bound[T: Type, S[_]: Type](x: Expr[S[T]]): Expr[S[T]] = '{
25+
val y: S[T] = $x
26+
y
27+
}
28+
}

0 commit comments

Comments
 (0)