Skip to content

Wrong overload resolution when expanding macro call #7110

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

Closed
biboudis opened this issue Aug 27, 2019 · 4 comments
Closed

Wrong overload resolution when expanding macro call #7110

biboudis opened this issue Aug 27, 2019 · 4 comments

Comments

@biboudis
Copy link
Contributor

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.

@nicolasstucki
Copy link
Contributor

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.

@nicolasstucki
Copy link
Contributor

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.

@anatoliykmetyuk
Copy link
Contributor

Do we need it before we can release RC18?

@biboudis
Copy link
Contributor Author

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

@anatoliykmetyuk anatoliykmetyuk removed this from the 0.21 Tech Preview milestone Dec 16, 2019
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 16, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 16, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 18, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 20, 2020
wip

WIP

wip
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 24, 2020
wip

WIP

wip
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 27, 2020
wip

WIP

wip
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 27, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 31, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 31, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 31, 2020
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 31, 2020
To avoid wrong member selection when unpickling we must have qualifiers that have the same type as when it was pickled. This implies that we cannot expand the holes durring unplickling as
the expansion of a qualifier could have a more precise type. To be able to unpickle a hole
without expanding it we must know it's type, hence it must be pickled.

Once the pickled quote has been unpickled, we first replace all the type splices. After the
types are properly set we expand all the term holes.

Changes
* Types of holes are pickled in TASTy
* Pickled quotes are unpickled and after that the holes are expanded
* Improved debugging info for unpickled quotes
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Mar 31, 2020
To avoid wrong member selection when unpickling we must have qualifiers that have the same type as when it was pickled. This implies that we cannot expand the holes durring unplickling as
the expansion of a qualifier could have a more precise type. To be able to unpickle a hole
without expanding it we must know it's type, hence it must be pickled.

Once the pickled quote has been unpickled, we first replace all the type splices. After the
types are properly set we expand all the term holes.

Changes
* Types of holes are pickled in TASTy
* Pickled quotes are unpickled and after that the holes are expanded
* Improved debugging info for unpickled quotes
nicolasstucki added a commit that referenced this issue Apr 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants