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

Quoted type pattern for '[Map[k, v]] doesn't match when k is an OrType #21634

Open
felher opened this issue Sep 24, 2024 · 1 comment
Open

Quoted type pattern for '[Map[k, v]] doesn't match when k is an OrType #21634

felher opened this issue Sep 24, 2024 · 1 comment
Assignees
Labels
itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label

Comments

@felher
Copy link
Contributor

felher commented Sep 24, 2024

Compiler version

3.5.1

Minimized code

A simple macro that has a quoted type pattern for a 'Map[k, v]:

Macro.scala:

import scala.quoted.*

object Macro:
  inline def matchMap[T]: String =
    ${ matchMapImpl[T] }

  def matchMapImpl[T](using t: Type[T], q: Quotes): Expr[String] =
    t match
      case '[Map[k, v]] => Expr("Found map")
      case _            => Expr("Not a map")
@main def hello(): Unit =
  println(Macro.matchMap[Map[String, Boolean]])
  println(Macro.matchMap[Map["A" | "B", Boolean]])

Output

Found map
Not a map

Expectation

Found map
Found map

Notes

Maybe this is not a bug, maybe it is a limitation or I'm thinking wrong, but for me it is not entirely clear why it depends on the key type whether I can match it. I asked in metaprogramming on discord and nobody seemed to know either, so here we are.

Also, thanks for your fantastic work on scala <3

Workaround

If somebody finds this ticket, whether it is a bug or not, and needs a quick workaround: Match on the TypeRepr:

val tpe: TypeRepr = ???
val mapTycon = Symbol.requiredClass("scala.collection.immutable.Map").typeRef
tpe.asMatchable match
  case AppliedType(tycon, args) if tycon =:= mapTycon =>
    val keyRepr   = args(0)
    val valueRepr = args(1)
    keyRepr.asType match
      case '[k] =>
        valueRepr.asType match
          case '[v] => ... 

Now you have both k and v matched and it works even if k is an OrType, which you can then deconstruct further

@felher felher added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Sep 24, 2024
@hamzaremmal hamzaremmal self-assigned this Sep 24, 2024
@smarter
Copy link
Member

smarter commented Sep 24, 2024

Related but different issue for reference (since the same fix might apply to both): #16782

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label
Projects
None yet
Development

No branches or pull requests

3 participants