scala / scala3

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

Tuple decomposition in quotes pattern matching doesn't compile #16265

Closed prolativ closed 1 year ago

prolativ commented 1 year ago

Compiler version

Fails with: 3.2.1, 3.2.2-RC1-bin-20221030-eab19e3-NIGHTLY Used to work with 3.2.0

Minimized code

//> using scala "3.2.1"

import scala.quoted.*

class Foo(val value: Int)

def foo(exprs: Expr[Any])(using Quotes): Any =
  exprs match
    case '{ $tuple: (Foo *: tail) } =>
      val x = '{ ${tuple}.head.value }
      ???

Output

[error] ./repro/Macro.scala:10:18: undefined: ${
[error]   {
[error]     def $anonfun(using evidence$1: quoted.Quotes): quoted.Expr[(Foo *: tail)] = 
[error]       tuple
[error]     closure($anonfun)
[error]   }
[error] }.head[(Foo *: tail)].value.$asInstanceOf # -1: TermRef(TermRef(AppliedType(TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Tuple),Head),List(AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class *:),List(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class Foo), TypeRef(NoPrefix,type tail))))),value),$asInstanceOf$) at sbt-api
[error]       val x = '{ ${tuple}.head.value }
[error]

Expectation

Should compile, as in 3.2.0

dwijnand commented 1 year ago

This fails during the type assigning of the TypeApply for "$asInstanceOf$" (which for some reason prints as "$asInstanceOf") during post-typer (even though for some reason "at sbt-api" is printed...). The type assigner wants the widened TypeLambda instead finds a TermRef with NoType as its widening. The TermRef is Tuple.Head[Foo *: tail]#value.$asInstanceOf.type. During typer, while GADT constraints are still present, that's type is (Foo#value : Int) & Int, because Tuple.Head[Foo *: tail] can reduce to Foo.

So GADT constraints/casting and Match Type reduction/caching issues, AFAICT.

(edit) Oh, and where did that cast come from? From GADT casting of course..

prolativ commented 1 year ago

Bisected to https://github.com/lampepfl/dotty/pull/15872

nicolasstucki commented 1 year ago

This works now