Skip to content

ScalaTest macros #5491

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

Closed
64 of 66 tasks
liufengyun opened this issue Nov 22, 2018 · 7 comments
Closed
64 of 66 tasks

ScalaTest macros #5491

liufengyun opened this issue Nov 22, 2018 · 7 comments
Assignees

Comments

@liufengyun
Copy link
Contributor

liufengyun commented Nov 22, 2018

This is thread for issues about implementation of ScalaTest macros (related meta issue #5489)

TODOS

Issues

  private def liftSeq(args: Seq[Expr[Any]]): Expr[Seq[Any]] = args match {
    case x :: xs  => '{ (~x) +: ~(liftSeq(xs))  }
    case Nil => '(Seq(): Seq[Any])
  }
@liufengyun
Copy link
Contributor Author

While working on ScalaTest, generally quote/splice improves a lot experience (though we still lack useful constructors #5567 ).

However, there is a potential problem, which is encountered when working on ScalaTest. There are two projects in ScalaTest:

  • Scalactic
  • Scalactic-Macros

In Scala2, Scalactic depends on Scalactic-Macros. In Scala 3, if we use quote/splice, Scalactic-Macros has to dependent on Scalactic to resolve names. This creates mutual dependencies!

If there is always mutual dependencies between macros project and its main project, quotes & splices will be useless for writing macros. Macro authors will be forced to use constructors & extractors to break the cycles.

@LPTK
Copy link
Contributor

LPTK commented Jan 15, 2019

If there is always mutual dependencies between macros project and its main project, quotes & splices will be useless for writing macros.

Can't you define the macros in the same project as the classes they quote? In both scala.reflect and Squid, that's how it works. It's just that you won't be able to call these macros from the same project.

For example, in scala.reflect you can write:

class A { val x = 42 }
def A: Int = macro `A macro`
def `A macro`(c: whitebox.Context): c.Expr[Int] = {
  c.universe.reify{new A().x}  // similar to a typed quote
}

@liufengyun
Copy link
Contributor Author

liufengyun commented Jan 15, 2019

@LPTK If the macros are not used in the main project, then it makes sense to merge the two projects. This is the walkaround I took dotty-staging/scalatest@642050c for ScalaTest.

However, I assume there are a lot of projects where the macros are used in the main project and refer to symbols defined in the main project, then things become subtle.

@liufengyun
Copy link
Contributor Author

liufengyun commented Jan 15, 2019

ScalaTest use Context.parse and Context.typecheck to implement assertCompiles, assertTypeError and assertDoesNotCompile, which are not available in Dotty (source):

      val tree = c.parse("{ "+codeStr+" }")
      if (!containsAnyValNullStatement(c)(List(tree))) {
        c.typeCheck(tree) // parse and type check code snippet
  • add show for Type[T] link

@liufengyun
Copy link
Contributor Author

@nicolasstucki Just discussed with @cheeseng and @bvenners, I learned that macros like assertDoesNotCompile are super useful for library authors.

Github search for assertDoesNotCompile shows 299 results.

@nicolasstucki
Copy link
Contributor

@liufengyun can we close this issue? All the macro related issues have been fixed. All remaining tasks have their own issue.

@liufengyun
Copy link
Contributor Author

We may close now. We need to make an upstream PR after the meta-programming API refactoring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants