Dotty: Wrong overload resolution when expanding macro call

Created on 27 Aug 2019  路  4Comments  路  Source: lampepfl/dotty

minimized code

Macro definition:

import scala.quoted._

object Macros {

  inline def m[R](sym: Symantics[R]) : R = ${  mImpl[R]('{sym}) }

  def mImpl[R: Type](sym: Expr[Symantics[R]]) given (qctx: QuoteContext): Expr[R] =  '{
    $sym.Meth(42)
  }
}

trait Symantics[R]  {
  def Meth(exp: Int): R
  def Meth(): R
}

Use:

import scala.quoted._
import Macros._

object Test {
  def main(args: Array[String]): Unit = {

    val sym = new Symantics[Int] {
      def Meth(exp: Int): Int = exp
      def Meth(): Int = 42
    }

    val test = m[Int](sym)
  }
}

expectation

Overloading should work. Instead it reports:

8 |    $sym.Meth(42)
  |    ^^^^^^^^^^^^
  |    wrong number of arguments at <no phase> for (): Int: ((): Int)(sym.Meth), expected: 0, found: 1
  | This location is in code that was inlined at Test_2.scala:13

If I remove the macro call it works (TASTy problem), if the Symantics is not parametric it also works. I don't think that it directly related to #7022 but it is definitely in the same area (@smarter WDYT?). BTW, the <no phase> in the error is also a bug I assume.

metaprogramming pickling advanced bug

All 4 comments

It looks like the issue is starts at this line.

        val d = qualType.findMember(name, pre).atSignature(sig)

where qualType and pre are TermRef(NoPrefix,val sym) which is a Symantics[Int].

findMember returns

<SingleDenotation of type MethodType(List(), List(), TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),module scala),class Int))> 
<and> 
<SingleDenotation of type MethodType(List(exp), List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),module scala),Int)), TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),module scala),class Int))>

Which kind of looks correct except that the return type in the signature that we are looking for is Object and not Int.

The issue is that when we pickle, we see the signature from Symantics[R] with a generic R and then when we unpickle and will in the prefix hole, the prefix becomes Symantics[Int] changing the signatures.

Do we need it before we can release RC18?

I moved it on the next one! It is not a blocker.

Was this page helpful?
0 / 5 - 0 ratings