Skip to content

Commit f277f19

Browse files
committed
step 27: not again! a crash in RefChecks!
java.lang.AssertionError: assertion failed: transformCaseApply: name = temp$macro$1 tree = temp$macro$1 / class scala.reflect.internal.Trees$Ident while compiling: /Users/xeno_by/Projects/macrology201/core/src/main/scala/Test.scala during phase: globalPhase=refchecks, enteringPhase=uncurry library version: version 2.11.0 compiler version: version 2.11.0 reconstructed args: -Ydead-code -bootclasspath /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/lib/JObjC.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/classes:/Users/xeno_by/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.0.jar -optimise -Yinline -Yclosure-elim -Yinline-handlers -Yconst-opt -classpath /Users/xeno_by/Projects/macrology201/core/target/scala-2.11/classes:/Users/xeno_by/Projects/macrology201/macros/target/scala-2.11/classes:/Users/xeno_by/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.11.0.jar last tree to typer: type Test tree position: line 3 of /Users/xeno_by/Projects/macrology201/core/src/main/scala/Test.scala tree tpe: <notype> symbol: object Test symbol definition: class Test extends AnyRef (a ModuleClassSymbol) symbol package: <empty> symbol owners: object Test call site: object Test in package <empty> == Source file context for tree position == 0 class C { override def toString = "C" } 1 2 object Test { 3 def main(args: Array[String]): Unit = { 4 val x1 = new Optional(new C) 5 val x2 = x1.map(_.toString) 6 println(x2) at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$2.apply$mcV$sp(RefChecks.scala:1709) at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformCaseApply(RefChecks.scala:1517) at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:1707) at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transform(RefChecks.scala:111) Unfortunately, a simple transformer doesn't cut it, crashing the compiler during the refchecks phase. This is the little brother of the owner chain corruption issue, again caused by the internal details of how scalac's typechecker handles abstract syntax trees. The problem at hand is caused by the fact that the typechecker doesn't go into trees that are already typed, which means that it effectively ignores untyped trees inserted under typed trees, and that's exactly what our macro expands into. Later phases have an implicit assumption that all the ASTs are typed, and that's what crashes refchecks. If we inspect the expansion with -Xprint:typer, also enabling -Xprint-types, we can identify the culprit: def main(args: Array[String]): Unit = { val x1: Optional[C] = new Optional[C]{Optional[C]}{(value: C)Optional[C]}(new C{C}{()C}(){C}){Optional[C]}; val x2: Optional[String] = ({ val temp$macro$1: Optional[C] = (x1{x1.type}: Optional[C]){Optional[C]}; if (temp$macro$1.isEmpty{Boolean}) new Optional[Null]{Optional[Null]}{(value: Null)Optional[Null]}(null{Null(null)}){Optional[Null]} else new Optional[String]{Optional[String]}{(value: String)Optional[String]}(temp$macro$1.toString{()String}(){String}){Optional[String]}{Optional[String]} }{Optional[String]}: Optional[String]){Optional[String]}; scala.this{scala.type}.Predef.println{(x: Any)Unit}(x2{Optional[String]}){Unit} Here we see the tree "temp$macro$1.toString{()String}(){String}", which appears typed (has type information assigned to it), but one of its parts (a reference to `temp$macro$1`) is untyped. That's our guy.
1 parent cf36a66 commit f277f19

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

project/Build.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ object MyBuild extends Build {
3535
"core",
3636
file("core"),
3737
settings = buildSettings ++ Seq(
38-
scalacOptions += "-optimize"
38+
scalacOptions += "-optimize",
39+
scalacOptions += "-Xprint:typer",
40+
scalacOptions += "-Xprint-types"
3941
)
4042
) dependsOn(macros)
4143
}

0 commit comments

Comments
 (0)