Skip to content
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

Pattern term of CaseDef is an internal ClassInfo that crashes when matched on #20458

Closed
tschuchortdev opened this issue May 22, 2024 · 1 comment · Fixed by #20468
Closed
Assignees
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:bug itype:crash
Milestone

Comments

@tschuchortdev
Copy link

Compiler version

3.3.3

Minimized code

case class Foo()
extension (self: Foo) {
  inline def matchCustom[R](inline matchExpr: Foo => R): R = ${matchCustomImpl[R]('self, 'matchExpr)}
}

private def matchCustomImpl[R: Type](self: Expr[Foo], matchExpr: Expr[Foo => R])(using q: Quotes): Expr[R] = {
  import q.reflect.*

  printTastyTree(matchExpr.asTerm)

  val cases = matchExpr.asTerm match
    case Inlined(_, _,
      Block(
        List(
          DefDef(
            lambdaName,
            List(TermParamClause(List(ValDef(lambdaParamName, lambdaParamType, _)))),
            _,
            Some(Match(Ident(matchVarName), cases))
          )
        ),
        Closure(Ident(closureName), _)
      )
    ) if closureName == lambdaName && matchVarName == lambdaParamName =>
        cases

    case _ => report.errorAndAbort("Must be a lambda with top-level match expression", matchExpr)

  val _ = cases.map { case CaseDef(pattern, guard, _) =>
      val t = pattern.symbol.termRef.simplified.widenTermRefByName
      // Assertion error here:
      t.asType match
         case '[t] => ()
  }

  '{ $matchExpr($self) }
}


// other file --------------------
val foo = Foo()

foo.matchCustom {
   case _: Any => ()
}

Output (click arrow to expand)

Exception occurred while executing macro expansion.
[error]    |java.lang.AssertionError: assertion failed: ClassInfo(ThisType(TypeRef(NoPrefix,module class scala)), class Any, List())
foo.matchCustom {
[error]    |    ^
[error]    |Exception occurred while executing macro expansion.
[error]    |java.lang.AssertionError: assertion failed: ClassInfo(ThisType(TypeRef(NoPrefix,module class scala)), class Any, List())
[error]    |    at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error]    |    at dotty.tools.dotc.core.Types$TypeBounds.<init>(Types.scala:5178)
[error]    |    at dotty.tools.dotc.core.Types$RealTypeBounds.<init>(Types.scala:5254)
[error]    |    at dotty.tools.dotc.core.Types$TypeBounds$.apply(Types.scala:5298)
[error]    |    at dotty.tools.dotc.core.Types$TypeBounds.derivedTypeBounds(Types.scala:5186)
[error]    |    at dotty.tools.dotc.core.ConstraintHandling.op$proxy2$1(ConstraintHandling.scala:314)
[error]    |    at dotty.tools.dotc.core.ConstraintHandling.addOneBound(ConstraintHandling.scala:314)
[error]    |    at dotty.tools.dotc.core.ConstraintHandling.addOneBound$(ConstraintHandling.scala:29)
[error]    |    at dotty.tools.dotc.core.ProperGadtState.addOneBound(GadtConstraint.scala:286)
[error]    |    at dotty.tools.dotc.core.ConstraintHandling.addBoundTransitively(ConstraintHandling.scala:370)
[error]    |    at dotty.tools.dotc.core.ConstraintHandling.addBoundTransitively$(ConstraintHandling.scala:29)
[error]    |    at dotty.tools.dotc.core.ProperGadtState.addBoundTransitively(GadtConstraint.scala:286)
[error]    |    at dotty.tools.dotc.core.GadtState.addBound(GadtConstraint.scala:232)
[error]    |    at dotty.tools.dotc.core.GadtState.addBound$(GadtConstraint.scala:153)
[error]    |    at dotty.tools.dotc.core.ProperGadtState.addBound(GadtConstraint.scala:286)
[error]    |    at dotty.tools.dotc.core.TypeComparer.gadtAddBound(TypeComparer.scala:119)
[error]    |    at dotty.tools.dotc.core.TypeComparer.narrowGADTBounds(TypeComparer.scala:2071)
[error]    |    at dotty.tools.dotc.core.TypeComparer.compareGADT$1(TypeComparer.scala:567)
[error]    |    at dotty.tools.dotc.core.TypeComparer.thirdTryNamed$1(TypeComparer.scala:571)
[error]    |    at dotty.tools.dotc.core.TypeComparer.thirdTry$1(TypeComparer.scala:625)
[error]    |    at dotty.tools.dotc.core.TypeComparer.secondTry$1(TypeComparer.scala:550)
[error]    |    at dotty.tools.dotc.core.TypeComparer.compareNamed$1(TypeComparer.scala:331)
[error]    |    at dotty.tools.dotc.core.TypeComparer.firstTry$1(TypeComparer.scala:337)
[error]    |    at dotty.tools.dotc.core.TypeComparer.recur(TypeComparer.scala:1471)
[error]    |    at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:208)
[error]    |    at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:218)
[error]    |    at dotty.tools.dotc.core.TypeComparer.topLevelSubType(TypeComparer.scala:128)
[error]    |    at dotty.tools.dotc.core.TypeComparer$.topLevelSubType(TypeComparer.scala:2942)
[error]    |    at dotty.tools.dotc.core.Types$Type.$less$colon$less(Types.scala:1062)
[error]    |    at scala.quoted.runtime.impl.QuoteMatcher.runMatch$1(QuoteMatcher.scala:380)
[error]    |    at scala.quoted.runtime.impl.QuoteMatcher.$eq$qmark$eq(QuoteMatcher.scala:451)
[error]    |    at scala.quoted.runtime.impl.QuoteMatcher.liftedTree1$1(QuoteMatcher.scala:132)
[error]    |    at scala.quoted.runtime.impl.QuoteMatcher.treeMatch(QuoteMatcher.scala:133)
[error]    |    at scala.quoted.runtime.impl.QuotesImpl$TypeMatch$.unapply(QuotesImpl.scala:3179)
[error]    |    at com.tschuchort.hkd.HkdFor$package$.matchCustomImpl$$anonfun$1(HkdFor.scala:51)
[error]    |    at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error]    |    at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error]    |    at scala.collection.immutable.List.map(List.scala:246)
[error]    |    at com.tschuchort.hkd.HkdFor$package$.matchCustomImpl(HkdFor.scala:55)
[error]    |    at com.tschuchort.hkd.HkdFor$package$.inline$matchCustomImpl(HkdFor.scala:25)
[error]    |
[error] 58 |      case _: Any => ()
[error] 59 |    }
[error]    |----------------------------------------------------------------------------
[error]    |Inline stack trace
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Macro.scala:22
[error] 22 |  inline def matchCustom[R](inline matchExpr: Foo => R): R = ${matchCustomImpl[R]('self, 'matchExpr)}
[error]    |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]     ----------------------------------------------------------------------------

The same kind of issue also occurs sometimes when only matching on the TypeRepr directly instead of the quoted Type.

@tschuchortdev tschuchortdev added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels May 22, 2024
@jchyb jchyb self-assigned this May 24, 2024
@jchyb
Copy link
Contributor

jchyb commented May 24, 2024

Minimised:
Main.scala:

def main() = matchCustom()

Macro.scala:

import scala.quoted._

inline def matchCustom(): Unit = ${ matchCustomImpl }

private def matchCustomImpl(using q: Quotes): Expr[Unit] = {
  import q.reflect.*
  val any = TypeRepr.of[Any].typeSymbol
  println(any.termRef.widenTermRefByName) // should not be `ClassInfo`
  any.termRef.widenTermRefByName.asType match
    case '[t] => ()
  '{ () }
}

@jchyb jchyb added the area:metaprogramming:reflection Issues related to the quotes reflection API label May 24, 2024
@Gedochao Gedochao removed the stat:needs triage Every issue needs to have an "area" and "itype" label label Jun 3, 2024
@Kordyjan Kordyjan added this to the 3.5.1 milestone Jul 3, 2024
WojciechMazur added a commit that referenced this issue Jul 10, 2024
…TermRefByName" to LTS (#21152)

Backports #20468 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:bug itype:crash
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants