question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot call macro defined in the same source file error

See original GitHub issue

Compiler version

3.0.1-RC1

Minimized code

MainMacro.scala

import scala.quoted.*

case class Wrapper[T](t: T) extends MainMacro[T]

trait MainMacro[U] { this: Wrapper[U] => 
  inline def showTypeRepr: String = ${ MainMacro.showTypeReprImpl[U]}
}

object MainMacro {
  def showTypeReprImpl[U: Type](using Quotes): Expr[String] = {
      import quotes.reflect.*
 
      val tpe = TypeRepr.of[U]

      Expr(tpe.toString)
  }
}

Test1.scala

object TestData {
  case class Person(name: String, age: Int)
}

class Test1 {

  import TestData.*

  // Notice that without inline does not work also
  inline def in(fun: => Any): Any = fun

  in {
    Wrapper(Person("a", 1)).showTypeRepr
  }
}

Output

$ mkdir classes
$ scalac -3.0.2-RC1 -d classes MainMacro.scala
$ scalac -3.0.2-RC1 -d classes -cp classes Test1.scala
-- Error: Test1.scala:13:28 ----------------------------------------------------
13 |    Wrapper(Person("a", 1)).showTypeRepr
   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |    Cannot call macro class Person defined in the same source file
   | This location contains code that was inlined from Test1.scala:13
1 error found

Expectation

It should compile, I guess.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:3
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

6reactions
nicolasstuckicommented, Jun 27, 2022

How I fixed it

  • I looked for the Cannot call macro class Person defined in the same source file message in the compiler. Specifically the Cannot call macro substring. I found this error reporting https://github.com/lampepfl/dotty/blob/16ded76a00a993492611faa1e56689aeba0a4aee/compiler/src/dotty/tools/dotc/typer/Inliner.scala#L1856
  • Above this we collect some dependencies that we will check. There are references to compiled code in that we need to be able to interpret the top-level splice. https://github.com/lampepfl/dotty/blob/16ded76a00a993492611faa1e56689aeba0a4aee/compiler/src/dotty/tools/dotc/typer/Inliner.scala#L1851
  • I printed the body and its dependencies and found that Person was listed in it. Person is only used in a type arguments and is therefore erased when compiled. Therfore it should not have been in the dependencies.
  • I checked macroDependencies and saw that we do not handle the TypeApply case. This implies that all symbol references in the type argument will be collected as if they were terms.
  • I added a case TypeApply that ignores the type argument and collects references from the prefix of the application. This worked.
  • Then I wondered if this should happen at all levels or just at level -1. We only interpret code that is at level -1 and therefore it should only be at level -1.
  • I checked the if I needed a guard for the TypeApply case and found that we already have an if (level != 1) ... else making sure that we are at level -1. I noticed that level == -1 was in another guard unnecessarily and removed it.

Note: when adding the case TypeApply(fun, _) => case I used by mistake foldOver(syms, fun) instead of apply(syms, fun). This made the logic ignore Ident prefixes of the application and therefore some dependencies were identified. This made some tests fail because they were expected use suspension of the compilation unit that contained the dependency.

1reaction
cheesengcommented, Aug 17, 2021

@mbore @nicolasstucki @adamw, Fyi I updated the example in https://github.com/cheeseng/scala3-inline-problem to use scala 3.0.2-RC1 but unfortunately it still encounters the same error:

cheeseng@cheeseng-RAVEN:~/git/scala3-inline-problem$ sbt clean test
[info] welcome to sbt 1.5.2 (GraalVM Community Java 1.8.0_302)
[info] loading global plugins from /home/cheeseng/.sbt/1.0/plugins
[info] loading project definition from /home/cheeseng/git/scala3-inline-problem/project
[info] loading settings for project root from build.sbt ...
[info] set current project to scala3-simple (in build file:/home/cheeseng/git/scala3-inline-problem/)
[success] Total time: 0 s, completed Aug 17, 2021 9:01:21 PM
[info] compiling 1 Scala source to /home/cheeseng/git/scala3-inline-problem/target/scala-3.0.2-RC1/classes ...
[warn] -- Warning: /home/cheeseng/git/scala3-inline-problem/src/main/scala/MainMacro.scala:15:6 
[warn] 15 |      '{${Expr(tpe.toString)}}
[warn]    |      ^^^^^^^^^^^^^^^^^^^^^^^^
[warn]    |Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ.
[warn] one warning found
[warn] one warning found
[info] compiling 1 Scala source to /home/cheeseng/git/scala3-inline-problem/target/scala-3.0.2-RC1/test-classes ...
[error] -- Error: /home/cheeseng/git/scala3-inline-problem/src/test/scala/Test1.scala:13:28 
[error] 13 |    Wrapper(Person("a", 1)).showTypeRepr 
[error]    |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]    |    Cannot call macro class Person defined in the same source file
[error]    | This location contains code that was inlined from Test1.scala:13
[error] one error found
[error] one error found
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 4 s, completed Aug 17, 2021 9:01:25 PM
Read more comments on GitHub >

github_iconTop Results From Across the Web

How can I fix a macro not being defined when I link a source ...
I have defined the UNICODE macro within my main file, however when I link the source file( "SythConsole.cpp") and compile. I get an...
Read more >
Developers - Cannot call macro defined in the same source file -
Coming soon: A brand new website interface for an even better experience!
Read more >
Basic macro for line number - Question - Scala Users
Attempting to write a simple macro in scala-3 that returns the line number at the calling site and am running into some trouble....
Read more >
Solving "Apparent Invocation of Macro Not Resolved" Problems
Apparent symbolic reference xxx not resolved. You are trying to resolve a macro variable in the same DATA step as the CALL SYMPUT...
Read more >
Chapter 4: The NASM Preprocessor
the preprocessor will be able to handle both types of macro call, by counting the parameters ... and then re-define it later in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found