Search code examples
scalascala-macrosscala-3izumi

How do I hang onto an izumi.reflect.Tag?


I've been using izumi.reflect.Tag to hold onto type info, and it works great. Except when I lose that type info at some point, and then I'm not sure how to get it back. Here's what I want to do:

case class Rule[T: Tag](lhs: String, rhs: Repr[T])

This is great. A Rule knows the type of the rhs inside it. Except...

val rules: List[Rule[?]] = // some list of rules
rules.foreach { r =>
  process(r)
}

def process[T: Tag](rule: Rule[T]): Unit = // side-effectful processing

At this point, I get could not find implicit value for izumi.reflect.Tag[T]. OK, no big surprise. That Tag can't be recovered, because it got mixed in with all the other tags in the List. But is there some way I can save the tag to get it back later?

I've tried

case class Rule[T: Tag](lhs: String, rhs: Repr[T]):
   val LightTypeTag = Tag[T].tag

and similar ways of holding onto the Tag so that I could do something like

process(r, r.tag)

def process[T: Tag](rule: Rule[T], tag: Tag[T]) = ...

or explicitly passing a Tag[T] into the process method, but I can't figure out how to do any of the following:

  1. Save a value of type Tag[T].
  2. Convert a value of type LightTypeTag back to a Tag[T].
  3. Some other combination of explicit saving and using some other values that will make this type check.

Any help greatly appreciated.


Solution

  • OK. Of course, after I posted this, I think I got an answer, but I'd like to be sure it's the right one. I realized I really wanted a Tag[T] and I couldn't figure out how to get one, but then I realized that I had a given Tag[T] available, so I did

    case class Rule[T: Tag](lhs: String, rhs: Repr[T]):
      val tag: Tag[T] = summon[Tag[T]]
    

    and if I add (using rule.tag) in the places where I'm missing the implicit Tag[T], things seem to work. Is this the right way to handle this?