New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scala quasiquote invalid behavior of the type system #9711
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9711?orig=1 |
@retronym said: What IDE are you using? Scala IDE's bug tracker is https://www.assembla.com/wiki/show/scala-ide/bug_reporting, and and IntellIJ's bug tracker is https://youtrack.jetbrains.com/issues/SCL |
John Reed (JohnReedlol) said (edited on Mar 21, 2016 5:00:27 AM UTC): ^ I don't think that this is just an IDE bug. The IDE gets its type information by querying. That being said, I tried two different versions of IntelliJ IntelliJ IDEA 2016.1 IntelliJ IDEA 15.0.4 Are you sure that there isn't something that is providing IntelliJ with the wrong types of the expressions? Like "toType" or :type or reflection or something? |
@som-snytt said: OK, so now that I know the format of external links in JIRA, using the "chain links" icon in the editor is kind of useless. Selecting the dummy text is impossible for anyone over 25. It makes me love github all the more. (I can make an ageist joke because I am of age?) |
@som-snytt said: |
@retronym said: The inherent difficulty in getting good IDE support when macros are allowed to compute arbitrary result types is why we created the distinction between "whitebox" and "blackbox" macros in Scala 2.11, and advice macro authors to favour blackbox macros when this is sufficiently powerful. Unfortunately pattern matching with quasiquotes really requires whitebox macros. |
John Reed (JohnReedlol) said: macro implementation has incompatible shape:
[error] required: (c: scala.reflect.macros.blackbox.Context)(x: c.Expr[=> T]): c.Expr[T] ^ It says that I can have a macro with that type signature, but when I copy and paste the type signature, I get identifier expected but '=>' found. c.Expr[=> T] ^ They should really remove the arrow from the warning in the type signature because you can't actually have a type signature like that. I ended up having to do: def impl[T](c: scala.reflect.macros.blackbox.Context)(x: c.Expr[T]): c.Expr[T] instead. Side side note: WRITING AND TESTING MACRO CODE IS A HUGE PAIN IN THE ASS. I mean If I have to write like 50 macros and each macro needs test cases and I need to keep adjusting the macros and re-writing them, I keep getting: macro implementation not found: apply
[error] (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) ^ I ended up having to put all my macro tests into one huge file and comment the whole thing out for every single compile. |
@retronym said: |
@retronym said: scala> import reflect.macros.blackbox._, language.experimental.macros
import reflect.macros.blackbox._
import language.experimental.macros
scala> def impl(c: Context) = c.literalUnit
warning: there was one deprecation warning; re-run with -deprecation for details
impl: (c: scala.reflect.macros.blackbox.Context)c.Expr[Unit]
scala> def m(a: => Int) = macro impl
<console>:18: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.blackbox.Context)(a: c.Expr[=> Int]): c.Expr[Unit]
or : (c: scala.reflect.macros.blackbox.Context)(a: c.Tree): c.Tree
found : (c: scala.reflect.macros.blackbox.Context): c.Expr[Unit]
number of parameter sections differ
def m(a: => Int) = macro impl
^
scala> def impl(c: Context)(a: c.Expr[=> Int]): c.Expr[Unit] = c.literalUnit
<console>:1: error: identifier expected but '=>' found.
def impl(c: Context)(a: c.Expr[=> Int]): c.Expr[Unit] = c.literalUnit
^
scala> def impl(c: Context)(a: c.Expr[Int]): c.Expr[Unit] = c.literalUnit
warning: there was one deprecation warning; re-run with -deprecation for details
impl: (c: scala.reflect.macros.blackbox.Context)(a: c.Expr[Int])c.Expr[Unit]
scala> def m(a: => Int) = macro impl
<console>:18: error: macro implementation has incompatible shape:
required: (c: scala.reflect.macros.blackbox.Context)(a: c.Expr[=> Int]): c.Expr[Unit]
or : (c: scala.reflect.macros.blackbox.Context)(a: c.Tree): c.Tree
found : (c: scala.reflect.macros.blackbox.Context)(a: c.Expr[Int]): c.Expr[Unit]
type mismatch for parameter a: c.Expr[=> Int] does not conform to c.Expr[Int]
def m(a: => Int) = macro impl
^ The workaround is to use macro implementations from |
@som-snytt said: |
John Reed (JohnReedlol) said (edited on Mar 23, 2016 7:16:37 PM UTC): Dude. I'm not a professional developer and I'm not even 23. I just need to replace my debug tools from using function calls to using macros and I'm on macro number 4. But I'm sure that when I'm done with this re-write I will get it right. Anyway, @jason Zaugg - how do I make it so that in my SBT project I only compile the macros and nothing else and then I only compile the macro tests and nothing else? I don't want to run into "macro implementation not found" anymore. My sbt project has two files with macros in it: "src/main/scala/package/Macros1.scala", and it has two files with macro tests in it: "src/test/scala/package/Tests1.scala", If I'm going to be modifying these files, would it be better to do like "sbt console :load src/test/scala/package/Tests1.scala" or "sbt test:compile"? |
@SethTisue said: |
@som-snytt said: On my first job, at eighteen, when a client on the phone began, "I'm a professional programmer...," we knew it was trouble. |
There's something really off about the type inference when I use quasiquotes
Take this example (from Programming Scala book, 2nd Edition):
^ Everything works. Now look at what happens when I ask for the types:
type of "statements":
Pattern: statements: scala.Seq[Trees#Tree]
type of "statement":
statement: Trees#Tree
Okay. Now I put these type annotations on "statement" and "statements" and compile
Compile/Run:
{quote}> test:run
[info] Compiling 1 Scala source to /home/johnreed/sbtProjects/scala-trace-debug/target/scala-2.11/test-classes...
[error] /home/johnreed/sbtProjects/scala-trace-debug/src/test/scala/mataprogramming/invariant2.scala:29: type mismatch;
[error] found : scala.reflect.api.Trees#Tree
[error] required: context.universe.Tree
[error] val exceptionMessage = s"FAILURE! $predicateAsString == false, for statement: " + showCode(statement)
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 0 s, completed Mar 20, 2016 5:40:33 PM
{quote}
This is very peculiar. The type inference told me that "statement" IS of type Trees#Tree
What if I annotate it with "context.universe.Tree" instead
The IDE says "expression of type Tree#Tree does not conform to type context.universe.Tree", but it compiles. What is going on with the wacky type inference here?
The text was updated successfully, but these errors were encountered: