-
-
Save chris-martin/35b06c826a874a6a42a418ee2614751a to your computer and use it in GitHub Desktop.
> scala ~/.ivy2/cache/com.lihaoyi/scalatags_2.11/jars/scalatags_2.11-0.6.0.jar -Xprint:typer -e "scalatags.Text.all" | |
java.lang.NullPointerException | |
at java.lang.Class.forName0(Native Method) | |
at java.lang.Class.forName(Class.java:348) | |
at scala.reflect.internal.util.ScalaClassLoader$$anonfun$tryClass$1.apply(ScalaClassLoader.scala:43) | |
at scala.reflect.internal.util.ScalaClassLoader$$anonfun$tryClass$1.apply(ScalaClassLoader.scala:43) | |
at scala.util.control.Exception$Catch$$anonfun$opt$1.apply(Exception.scala:119) | |
at scala.util.control.Exception$Catch$$anonfun$opt$1.apply(Exception.scala:119) | |
at scala.util.control.Exception$Catch.apply(Exception.scala:103) | |
at scala.util.control.Exception$Catch.opt(Exception.scala:119) | |
at scala.reflect.internal.util.ScalaClassLoader$class.tryClass(ScalaClassLoader.scala:42) | |
at scala.reflect.internal.util.ScalaClassLoader$class.tryToInitializeClass(ScalaClassLoader.scala:39) | |
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.tryToInitializeClass(ScalaClassLoader.scala:101) | |
at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:63) | |
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101) | |
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22) | |
at scala.tools.nsc.JarRunner$.run(MainGenericRunner.scala:13) | |
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29) | |
at scala.tools.nsc.JarRunner$.runJar(MainGenericRunner.scala:25) | |
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:69) | |
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:87) | |
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98) | |
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103) | |
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) | |
> scala -Xprint:typer -e "()" | |
Exception in thread "main" java.net.UnknownHostException: renzo: renzo: Name or service not known | |
at java.net.InetAddress.getLocalHost(InetAddress.java:1505) | |
at scala.tools.nsc.io.Socket$.localhost(Socket.scala:28) | |
at scala.tools.nsc.CompileSocket.getsock$1(CompileSocket.scala:175) | |
at scala.tools.nsc.CompileSocket.getOrCreateSocket(CompileSocket.scala:190) | |
at scala.tools.nsc.ScriptRunner.compileWithDaemon(ScriptRunner.scala:70) | |
at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$compile$1(ScriptRunner.scala:113) | |
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:161) | |
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:129) | |
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:129) | |
at scala.tools.nsc.util.package$.trackingThreads(package.scala:43) | |
at scala.tools.nsc.util.package$.waitingForThreads(package.scala:27) | |
at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:128) | |
at scala.tools.nsc.ScriptRunner.runCommand(ScriptRunner.scala:222) | |
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:85) | |
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98) | |
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103) | |
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) | |
Caused by: java.net.UnknownHostException: renzo: Name or service not known | |
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) | |
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) | |
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) | |
at java.net.InetAddress.getLocalHost(InetAddress.java:1500) | |
... 16 more |
Getting closer, although -e
doesn't seem to do what I think it does.
scala -cp ~/.ivy2/cache/com.lihaoyi/scalatags_2.11/jars/scalatags_2.11-0.6.0.jar -nocompdaemon -Xprint:typer -e "scalatags.Text.all"
[[syntax trees at end of typer]] // scalacmd6163883395223728752.scala
package <empty> {
object Main extends scala.AnyRef {
def <init>(): Main.type = {
Main.super.<init>();
()
};
def main(args: Array[String]): Unit = {
final class $anon extends scala.AnyRef {
def <init>(): <$anon: AnyRef> = {
$anon.super.<init>();
()
};
scalatags.Text.all
};
{
new $anon();
()
}
}
}
}
Most of the junk you see is what the Scala REPL adds to convert expressions to Scala compilation units. You're implicitly pointing out no other REPL does that, but that's Scala for you. You can run scala -Xprint:typer
without -e
to see it happen in real time.
But to be sure, there are docs on -Xprint
:
$ scala -X
[...]
-Xprint:<phases> Print out program after <phases>
[...]
And for completeness: typer
is the phase doing typechecking and implicit resolution (they're intertwined), so it also shows the inserted implicits and it's invaluable constantly when figuring out how Scala is mangling your program.
To have a slightly more interesting example:
$ scala -Xprint:typer -e 'implicitly[Int <:< Any]'
[[syntax trees at end of typer]] // scalacmd7742517026832451635.scala
package <empty> {
object Main extends scala.AnyRef {
def <init>(): Main.type = {
Main.super.<init>();
()
};
def main(args: Array[String]): Unit = {
final class $anon extends scala.AnyRef {
def <init>(): <$anon: AnyRef> = {
$anon.super.<init>();
()
};
scala.this.Predef.implicitly[<:<[Int,Any]](scala.this.Predef.$conforms[Int])
};
{
new $anon();
()
}
}
}
}
The only interesting part of that is scala.this.Predef.implicitly[<:<[Int,Any]](scala.this.Predef.$conforms[Int])
, which shows the implicit argument $conforms[Int]
passed to implicitly
.
So what I'd recommend: take your example code using mistery implicits, pass it to -e
or put it in a file or paste it at the REPL, and use -Xprint:typer
to see the inserted implicits. Actually, scalac ... -Xprint:typer Foo.scala
would avoid inserting the REPL junk, so you'd only have the other junk from the typechecker. But I still think that can be rather useful.
The other approach, when it works, it to use an IDE highlighting implicits and use "open implicit", but those are annoying in different ways and you have to use Eclipse/ScalaIDE over IntelliJ for reliable results.
I've never used
-e
and I don't know how buggy it is (though it works here).scala foo.jar
looks bad, I think you wantscala -cp foo.jar
. The latter is weird and works here (see below).It seems you're combining three things:
-nocompdaemon
to the Scala command line.java.net.InetAddress.getLocalHost
, your hostname is renzo and your/etc/hosts
or whatever doesn't maprenzo
to some IP (say,127.0.0.1
, but some Linux distros use a different loopback address like127.0.1.1
because of... crazy stuff).I've seen
getLocalHost
-like stuff being pickier on mild misconfigurations than almost every other software on the planet.See also https://gist.github.com/retronym/824183 for a reasonable example.