scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.87k stars 1.06k forks source link

Package private method cannot be matched using quotes API #15676

Open WojciechMazur opened 2 years ago

WojciechMazur commented 2 years ago

Community build regression for https://github.com/ciaraobrien/dottytags (maintainer @ciaraobrien) Based on Open Community Build #1858 Part of https://github.com/lampepfl/dotty/issues/15647 regressions tracker

Compiler version

Works with 3.1.0 Fails in 3.1.1 Fails in 3.2.1-RC1-bin-20220712-7e20b81-NIGHTLYon` instead).

Minimized code

package dottytags

import scala.quoted.*

class TagClass private[dottytags] (val name: String)
private[dottytags] object TagClass:
  def apply(name: String): TagClass = new TagClass(name)

inline def tag(inline name: String): TagClass = ${ tagClassMacro('name) }
private def tagClassMacro(nameExpr: Expr[String])(using Quotes): Expr[TagClass] = {
  val tgExpr = Expr(TagClass(nameExpr.value.get))
  TagClassFromExpr.unapply(tgExpr).foreach(println) // To trigger failure
  tgExpr
}

private given TagClassFromExpr: FromExpr[TagClass] with
  def unapply(x: Expr[TagClass])(using Quotes): Option[TagClass] =
    x match
      case '{ TagClass(${ Expr(name: String) }) } =>
        println(s"in apply, name=$name)")
        Some(TagClass(name))
      case _ =>
        import quotes.reflect.report
        report.error(s"Failed to extract value from ${x.show}")
        None

private given TagClassToExpr: ToExpr[TagClass] with
  def apply(x: TagClass)(using Quotes): Expr[TagClass] = '{ TagClass(${ Expr(x.name) }) }
// usage.scala
import dottytags.*
@main def Test() = println(tag("html"))

Output

-- Error: test.scala:4:13 -------------------------------------------------------------------------------------------------------
4 |  println(tag("html"))
  |          ^^^^^^^^^^^
  |          Failed to extract value from dottytags.macro$package.inline$TagClass.apply("html")
1 error found

Expectation

Compiles with the same output as in 3.1.0:

in apply, name=html)
dottytags.TagClass@5b3a8bea
mbovel commented 2 years ago

How can I reproduce?

I tried sbt "scalac test.scala" on main, scala-cli compile -S 3.2.1-RC1-bin-20220712-7e20b81-NIGHTLY test.scala and scala-cli compile -S 3.1.1 test.scala but all compile successfully. Do I need to set additional options?

WojciechMazur commented 2 years ago

@mbovel Sorry, I forget to include the second file that actually uses the macro. I've updated the issue reproducer

KacperFKorban commented 2 years ago

I managed to bisect it and it looks like the first bad commit is: https://github.com/lampepfl/dotty/commit/0b072d6b7df6d9c65d6ffce779c3417df42b47bd

I checked and it seems that adding makeInlineable here fixes the issue and doesn't break the compilation for the snippet from https://github.com/lampepfl/dotty/issues/13546. And I don't know why this change was introduced, since the PR only added one test case.

nicolasstucki commented 2 years ago

Minimized

package foo
import scala.quoted.*

private[foo] object Foo:
  def apply(): Int = ???

inline def test(): Unit = ${ testExpr() }

private def testExpr()(using Quotes): Expr[Unit] = {
  '{ Foo() } match
    case '{ Foo() } =>
  '{}
}
// usage.scala
def Test() = foo.test()