Skip to content

summonInline can't deduce summon, passed via type parameter [Regression] #11479

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
rssh opened this issue Feb 20, 2021 · 7 comments · Fixed by #11591
Closed

summonInline can't deduce summon, passed via type parameter [Regression] #11479

rssh opened this issue Feb 20, 2021 · 7 comments · Fixed by #11591
Assignees
Milestone

Comments

@rssh
Copy link
Contributor

rssh commented Feb 20, 2021

Compiler version

3.0.0-RC1
Latest Dotty nightly build version: 3.0.0-RC2-bin-20210219-aa7c21e-NIGHTLY

Minimized code

fixe X.scala:

package x

import scala.concurrent.Future
import scala.quoted._
import scala.compiletime._

trait CpsMonad[F[_]]

given FutureCpsMonad:  CpsMonad[Future] with {}


class SLLoop[F[_]:CpsMonad]:

 inline def apply(inline pf: PartialFunction[Any,Boolean]): Unit =
    ${
      SLLoop.loopImpl[F]('pf, '{summonInline[CpsMonad[F]]})
    }


object SLLoop:

    def loopImpl[F[_]:Type](pf: Expr[PartialFunction[Any,Boolean]], m:Expr[CpsMonad[F]])(using Quotes): Expr[Unit] =
      println(s"loopImpl: ${pf}")
      '{ }

file Main.scala

package x

import scala.concurrent.Future

object Main:

  def main(args:Array[String]):Unit =
    SLLoop[Future].apply{
      case "AAA" => true
    }

Output

Latest Dotty nightly build version: 3.0.0-RC2-bin-20210219-aa7c21e-NIGHTLY
[info] loading settings for project root from build.sbt ...
[info] set current project to test (in build file:/Users/rssh/tests/dotty/summon-inline/)
[info] Executing in batch mode. For better performance use sbt's shell
[info] compiling 2 Scala sources to /Users/rssh/tests/dotty/summon-inline/target/scala-3.0.0-RC2/classes ...
[error] -- Error: /Users/rssh/tests/dotty/summon-inline/src/main/scala/x/Main.scala:8:24 
[error] 8 |    SLLoop[Future].apply{
[error]    |    ^
[error]    |    cannot reduce summonFrom with
[error]    |     patterns :  case t @ _:x.CpsMonad[concurrent.Future]
[error]    | This location contains code that was inlined from package.scala:144
[error]    | This location contains code that was inlined from X.scala:16
[error] 9 |      case "AAA" => true
[error] 10 |    }
[error] one error found
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Expectation

Should compile.
(it works in 3.0.0-M3)

@rssh rssh added the itype:bug label Feb 20, 2021
@liufengyun
Copy link
Contributor

@rssh You can try to add transparent for the macro.

I'm wondering the code should compile even without transparent. This is related to usage of typeChecks in macros as well.

/cc: @nicolasstucki

@nicolasstucki
Copy link
Contributor

To have better code, should use Expr.summon instead in loopImpl instead of summonInline.

I will check why it does not find the implicit.

@liufengyun
Copy link
Contributor

Maybe we can improve the documentation of summonInline to say it should not be used in macros.

@rssh
Copy link
Contributor Author

rssh commented Feb 22, 2021

Note, that if we will change X to be:

package x

import scala.concurrent.Future
import scala.quoted._
import scala.compiletime._

trait CpsMonad[F[_]]

given FutureCpsMonad:  CpsMonad[Future] with {}


class SLLoop[F[_]:CpsMonad]:

 inline def apply(inline pf: PartialFunction[Any,Boolean]): Unit =
    ${
      SLLoop.loopImpl[F]('pf )
    }


object SLLoop:

    def loopImpl[F[_]:Type](pf: Expr[PartialFunction[Any,Boolean]])(using Quotes): Expr[Unit] =
      Expr.summon[CpsMonad[F]] match
        case Some(m) =>
              println(s"found, m= ${m}")
        case None =>
              println("not found")
      '{ }

Then the output of loopImpl (with the same 'Main.scala') is "not found".

@nicolasstucki
Copy link
Contributor

Side note

class SLLoop[F[_]:CpsMonad]: // We already have an implicit instance of CpsMonad[F] before inlining here
  inline def apply(inline pf: PartialFunction[Any,Boolean]): Unit =
    ${
      SLLoop.loopImpl[F]('pf, '{summon[CpsMonad[F]]}) // we can just summon it here
    }

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Feb 24, 2021

Minimized

trait Foo
given Foo: Foo with {}
inline def summonFoo(): Foo = scala.compiletime.summonInline[Foo]
def test: Unit = summonFoo()

It looks like we during the Inlining phase we cannot find top-level givens defined in other files. There is probably something missing in TreeMapWithImplicits.

@nicolasstucki
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment