Skip to content

Stripping generic type with asExprOf does not recover it in transparent inline when passing it to another function #22886

Open
@andrzejressel

Description

@andrzejressel

Compiler version

3.3.5
3.6.4
3.7.0-RC1

Minimized code

Macros.scala

import scala.quoted._

inline transparent def generateListPure(): List[?] = {
  ${ generateListPureImpl }
}

inline transparent def generateList(): List[?] = {
  ${ generateListImpl }
}

inline transparent def generateListWithMatch(): List[?] = {
  ${ generateListWithMatchImpl }
}

private def generateListPureImpl(using Quotes): Expr[List[?]] = {
  val myExpr = '{ List(1) }.asExprOf[List[?]]

  '{ $myExpr }
}

private def generateListImpl(using Quotes): Expr[List[?]] = {
  val myExpr = '{ List(1) }.asExprOf[List[?]]

  '{ doSomethingWithList($myExpr) }
}

private def generateListWithMatchImpl(using Quotes): Expr[List[?]] = {
  val myExpr = '{ List(1) }.asExprOf[List[?]]

  myExpr match {
    case '{ $typedList: List[in] } =>
      '{ doSomethingWithList($typedList) }
  }
}

private def doSomethingWithList[T](l: List[T]): List[T] = l

inline transparent def getInnerType[E](l: List[E]) = {
  ${ getInnerTypeImpl('l) }
}

private def getInnerTypeImpl[E: Type](l: Expr[List[E]])(using Quotes): Expr[String] = {
  val s = Type.show[E]
  Expr.apply(s)
}

Test.scala

@main
def main(): Unit = {
  val innerTypePure = getInnerType(generateListPure())
  val innerType = getInnerType(generateList())
  val innerTypeWithMatch = getInnerType(generateListWithMatch())

  println(s"Pure: $innerTypePure")
  println(s"Normal: $innerType")
  println(s"With match: $innerTypeWithMatch")
}

Output

Pure: scala.Int
Normal: scala.Any
With match: scala.Int

Expectation

Pure: scala.Int
Normal: scala.Int
With match: scala.Int

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions