forked from scala/scala
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
blackbox restriction #2: can't guide type inference
When an application of a blackbox macro still has undetermined type parameters after Scala’s type inference algorithm has finished working, these type parameters are inferred forcedly, in exactly the same manner as type inference happens for normal methods. This makes it impossible for blackbox macros to influence type inference, prohibiting fundep materialization.
- Loading branch information
Showing
12 changed files
with
100 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
test/files/neg/macro-blackbox-fundep-materialization.check
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Test_2.scala:7: Iso.materializeIso is not a valid implicit value for Iso[Test.Foo,L] because: | ||
hasMatchingSymbol reported error: type mismatch; | ||
found : Iso[Test.Foo,(Int, String, Boolean)] | ||
required: Iso[Test.Foo,Nothing] | ||
Note: (Int, String, Boolean) >: Nothing, but trait Iso is invariant in type U. | ||
You may wish to define U as -U instead. (SLS 4.5) | ||
val equiv = foo(Foo(23, "foo", true)) | ||
^ | ||
Test_2.scala:7: error: could not find implicit value for parameter iso: Iso[Test.Foo,L] | ||
val equiv = foo(Foo(23, "foo", true)) | ||
^ | ||
one error found |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-Xlog-implicits |
39 changes: 39 additions & 0 deletions
39
test/files/neg/macro-blackbox-fundep-materialization/Macros_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import scala.language.experimental.macros | ||
import scala.reflect.macros.BlackboxContext | ||
|
||
trait Iso[T, U] { | ||
def to(t : T) : U | ||
// def from(u : U) : T | ||
} | ||
|
||
object Iso { | ||
implicit def materializeIso[T, U]: Iso[T, U] = macro impl[T, U] | ||
def impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: BlackboxContext): c.Expr[Iso[T, U]] = { | ||
import c.universe._ | ||
import definitions._ | ||
import Flag._ | ||
|
||
val sym = c.weakTypeOf[T].typeSymbol | ||
if (!sym.isClass || !sym.asClass.isCaseClass) c.abort(c.enclosingPosition, s"$sym is not a case class") | ||
val fields = sym.typeSignature.declarations.toList.collect{ case x: TermSymbol if x.isVal && x.isCaseAccessor => x } | ||
|
||
def mkTpt() = { | ||
val core = Ident(TupleClass(fields.length) orElse UnitClass) | ||
if (fields.length == 0) core | ||
else AppliedTypeTree(core, fields map (f => TypeTree(f.typeSignature))) | ||
} | ||
|
||
def mkFrom() = { | ||
if (fields.length == 0) Literal(Constant(Unit)) | ||
else Apply(Ident(newTermName("Tuple" + fields.length)), fields map (f => Select(Ident(newTermName("f")), newTermName(f.name.toString.trim)))) | ||
} | ||
|
||
val evidenceClass = ClassDef(Modifiers(FINAL), newTypeName("$anon"), List(), Template( | ||
List(AppliedTypeTree(Ident(newTypeName("Iso")), List(Ident(sym), mkTpt()))), | ||
emptyValDef, | ||
List( | ||
DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))), | ||
DefDef(Modifiers(), newTermName("to"), List(), List(List(ValDef(Modifiers(PARAM), newTermName("f"), Ident(sym), EmptyTree))), TypeTree(), mkFrom())))) | ||
c.Expr[Iso[T, U]](Block(List(evidenceClass), Apply(Select(New(Ident(newTypeName("$anon"))), nme.CONSTRUCTOR), List()))) | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
C(Int) | ||
C(String) | ||
C(Nothing) |
16 changes: 16 additions & 0 deletions
16
test/files/run/macro-blackbox-materialization/Macros_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// For the full version of the test, take a look at run/t5923a | ||
|
||
import scala.reflect.macros.BlackboxContext | ||
import language.experimental.macros | ||
|
||
case class C[T](t: String) | ||
object C { | ||
implicit def foo[T]: C[T] = macro Macros.impl[T] | ||
} | ||
|
||
object Macros { | ||
def impl[T: c.WeakTypeTag](c: BlackboxContext) = { | ||
import c.universe._ | ||
reify(C[T](c.literal(weakTypeOf[T].toString).splice)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
object Test extends App { | ||
println(implicitly[C[Int]]) | ||
println(implicitly[C[String]]) | ||
println(implicitly[C[Nothing]]) | ||
} |
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
test/files/run/t5923c/Macros_1.scala → ...box-fundep-materialization/Macros_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
test/files/run/macro-whitebox-fundep-materialization/Test_2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// see the comments for macroExpandApply.onDelayed for an explanation of what's tested here | ||
object Test extends App { | ||
case class Foo(i: Int, s: String, b: Boolean) | ||
def foo[C, L](c: C)(implicit iso: Iso[C, L]): L = iso.to(c) | ||
|
||
{ | ||
val equiv = foo(Foo(23, "foo", true)) | ||
def typed[T](t: => T) {} | ||
typed[(Int, String, Boolean)](equiv) | ||
println(equiv) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// see neg/macro-blackbox-fundep-materialization and run/macro-whitebox-fundep-materialization | ||
object Test extends App { | ||
// do nothing | ||
} |