question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Missing a way to widen `quoted.Type` after pattern matching

See original GitHub issue

I’m not sure if this is a compiler issue or issue with my understanding but I am trying to write a macro along the lines of recovering-precise-types-using-patterns.

To be clear the example in the documentation works without type ascription but, with the macro being called as below, the type matching fails if there are no type ascriptions

Compiler version

3.0.0-RC1

Code

Main app

import upickle.default.{macroRW, readwriter, ReadWriter => RW, Writer}

abstract class MyObject:
  val ref: String
  inline def macroCall(inline args: Any*): String = ${ callImpl('this, 'args) }

class Thing(val ref: String) extends MyObject:
  // def something(i: Int, d: Double, s: String) = macroCall(i: Int, d: Double, s: String) // works - Why do I need the types here?
  def something(i: Int, d: Double, s: String) = macroCall(i, d, s) // fails

object TestApp:
  def main(args: Array[String]): Unit = 
    val res = Thing("aref").something(3, 3.14, "pi")

Macro

import scala.quoted.*
import upickle.default.Writer

def callImpl(obj: Expr[MyObject], argsExpr: Expr[Seq[Any]])(using Quotes): Expr[String] =
   import quotes.reflect.report
   argsExpr match
      case Varargs(argExprs) =>
         val argShowedExprs = argExprs.map {
            case '{ $arg: tp } =>
              val str = Type.show[tp]
              println(s"matched arg=$arg str=$str")

              Expr.summon[Writer[tp]] match
                case Some(showExpr) =>                  
                  '{ upickle.default.write($arg)($showExpr) }
                case None =>
                  report.error(s"could not find implicit for ${Type.show[Writer[tp]]}", arg); '{???}
         }
         val newArgsExpr = Varargs(argShowedExprs)
         '{ "[" + $newArgsExpr.mkString(",") + "]" }
         
      case _ =>
        report.error(s"Args must be explicit", argsExpr)
        '{???}

Output

matched arg='{ ... } str=i.type
[error] -- Error: /Users/ajr/dev/misc/scala3test/scala3test/src/ajr/scala3test/Test.scala:10:58 
[error] 10 |  def something(i: Int, d: Double, s: String) = macroCall(i, d, s)
[error]    |                                                          ^
[error]    |                   could not find implicit for upickle.default.Writer[i]
[error]    | This location contains code that was inlined from Test.scala:10
matched arg='{ ... } str=d.type
[error] -- Error: /Users/ajr/dev/misc/scala3test/scala3test/src/ajr/scala3test/Test.scala:10:61 
[error] 10 |  def something(i: Int, d: Double, s: String) = macroCall(i, d, s)
[error]    |                                                             ^
[error]    |                   could not find implicit for upickle.default.Writer[d]
[error]    | This location contains code that was inlined from Test.scala:10
matched arg='{ ... } str=s.type
[error] -- Error: /Users/ajr/dev/misc/scala3test/scala3test/src/ajr/scala3test/Test.scala:10:64 
[error] 10 |  def something(i: Int, d: Double, s: String) = macroCall(i, d, s)
[error]    |                                                                ^
[error]    |                   could not find implicit for upickle.default.Writer[s]
[error]    | This location contains code that was inlined from Test.scala:10

Expectation

I would expect the varargs arguments to have a type which could be matched

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
smartercommented, Mar 2, 2021

(note that this probably wouldn’t be an issue if Writer was contravariant in its type parameter)

0reactions
oderskycommented, Mar 5, 2021

@nicolasstucki Assigning to you to decide whether/how this should be fixed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

4. Pattern Matching - Programming Scala, 2nd Edition [Book]
Like methods, types can have names with a wide variety of characters. It has just one method, the unapply method the compiler needs...
Read more >
RegEx: Grabbing values between quotation marks
After encountering such state, regex engine backtrack to previous matching character and here regex is over and will move to next regex. \1...
Read more >
Quoted Code | Macros in Scala 3
Type variables in quoted patterns. Quoted code may contain types that are not known outside of the quote. We can match on them...
Read more >
Pattern Matching Support #165 - microsoft/TypeScript - GitHub
As I'm a big fan of it, I've written up some small examples on how I think pattern matching could look in TypeScript....
Read more >
14 Strings | R for Data Science - Hadley Wickham
Once you've mastered pattern matching, you'll learn how to apply those ideas with various stringr functions. 14.3.1 Basic matches. The simplest patterns match...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found