scala / scala3

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

Regression in `com-lihaoyi/fastparse` for inlines / term-dependant types #20286

Closed WojciechMazur closed 2 months ago

WojciechMazur commented 2 months ago

Based on OpenCB failure for com-lahaoyi/fastparse - build logs

Compiler version

Last good release: 3.5.0-RC1-bin-20240404-a7f00e2-NIGHTLY First bad release: 3.5.0-RC1-bin-20240405-85672a0-NIGHTLY Bisect points to f055ceef7c8dc96fbed17ffa69d37b2bb5846b98

Minimized code

// test.scala
implicit inline def LiteralStr(s: String)(implicit ctx: P[Any]): P[Unit] = ???

extension [T](inline parse0: P[T]) {
  inline def ~[V, R](inline other: P[V])(using
      ctx: P[?]
  ): P[R] = ${ MacroInlineImpls.parsedSequence0[T, V, R]('parse0, 'other) }

  inline def flatMapX[V](inline f: T => P[V]): P[V] =
    MacroInlineImpls.flatMapXInline[T, V](parse0)(f)
}

def deeper[$: P]: P[Int] = ???
def newline[$: P]: P[Unit] = ???
def blockBody[p: P]: P[Seq[Int]] = newline ~ deeper.flatMapX { i =>
  val y = LiteralStr("")(using ???)
  ???
}
// test.macros.scala
import scala.quoted.*

type P[+T] = ParsingRun[T]
trait ParsingRun[+T] {
  var successValue: Any
  def freshSuccessUnit(): ParsingRun[Unit]

}

object MacroInlineImpls {
  inline def flatMapXInline[T, V](
      lhs: ParsingRun[T]
  )(inline f: T => ParsingRun[V]): ParsingRun[V] = {
    f(lhs.successValue.asInstanceOf[T])
  }

  def parsedSequence0[T: Type, V: Type, R: Type](
      lhs: Expr[ParsingRun[T]],
      rhs: Expr[ParsingRun[V]]
  )(using quotes: Quotes): Expr[ParsingRun[R]] = {
    import quotes.reflect.*
    '{ $rhs.asInstanceOf[ParsingRun[R]] }
  }
}

Output

18 |  val y = LiteralStr("")(using ???)
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
   |Term-dependent types are experimental,
   |they must be enabled with a `experimental.dependent` language import or setting
   |----------------------------------------------------------------------------
   |Inline stack trace
   |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   |This location contains code that was inlined from sandbox.scala:3
 3 |implicit inline def LiteralStr(s: String)(implicit ctx: P[Any]): P[Unit] = ???
   |                                                                 ^^^^^^^
    ----------------------------------------

Expectation

The compiler should be be assuming to using the experimental term-depandant types, the library is not using them explicitly.

nicolasstucki commented 2 months ago

The issue is that we are trying to replace Unit with () in

 3 |implicit inline def LiteralStr(s: String)(implicit ctx: P[Any]): P[Unit] = ???