Skip to content
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

summonInline[B <:< A] compiles when quoted despite B not being a subtype of A #10709

Closed
maphi opened this issue Dec 8, 2020 · 2 comments · Fixed by #10781
Closed

summonInline[B <:< A] compiles when quoted despite B not being a subtype of A #10709

maphi opened this issue Dec 8, 2020 · 2 comments · Fixed by #10781
Assignees
Milestone

Comments

@maphi
Copy link

maphi commented Dec 8, 2020

Minimized code

// using 3.0.0-M2

import scala.quoted._
import scala.compiletime.summonInline

object Invalid {
  inline def apply[A, B]: Any = ${ invalidImpl[A, B] }

  def invalidImpl[A, B](using qctx: Quotes, tpeA: Type[A], tpeB: Type[B]): Expr[Any] = {
    '{summonInline[B <:< A]}
  }
}

/************ other file ************/

class A
class B extends A
println(Invalid[A, B]) // compiles as expected
println(Invalid[B, A]) // does also compile!

Expectation

'{summonInline[B <:< A]} should not compile when subtyping rules are violated

@maphi maphi added the itype:bug label Dec 8, 2020
@smarter
Copy link
Member

smarter commented Dec 8, 2020

invalidImpl evalutes to:

    def invalidImpl[A >: Nothing <: Any, B >: Nothing <: Any](using 
      qctx: quoted.Quotes
    , tpeA: quoted.Type[A], tpeB: quoted.Type[B]): quoted.Expr[Any] = 
      {
        '{
          {
            val t: B <:< A = <:<.refl[B].$asInstanceOf$[B <:< A]
            t:B <:< A
          }
        }.apply(qctx)
      }

So the implicit search happens early (and I don't see how it can succeed given that we don't know that B <:< A at this point?), unlike what the documentation of summonInline says:

The summoning is delayed until the call has been fully inlined.

It does work as expected if we remove invalidImpl and replace the apply method by:

inline def apply[A, B]: Any = summonInline[B <:< A]

@nicolasstucki
Copy link
Contributor

summonInline should no be inlined inside of the quote. The guard before inlining some code (Inliner.inlineCall(tree) in Typer) is missing that check.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 14, 2020
If an a call to an inline method is within a quote, this call must not be inlined.
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 14, 2020
If an a call to an inline method is within a quote, this call must not be inlined.

* Delay inlining within quotes.
* Disallow `inline def` within quotes. Same as `inline def` in `inline def`.
@nicolasstucki nicolasstucki linked a pull request Dec 14, 2020 that will close this issue
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 14, 2020
If an a call to an inline method is within a quote, this call must not be inlined.

* Delay inlining within quotes.
* Disallow `inline def` within quotes. Same as `inline def` in `inline def`.
nicolasstucki added a commit that referenced this issue Dec 14, 2020
Fix #10709: Add missing level check before inlining
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 15, 2020
@Kordyjan Kordyjan added this to the 3.0.0 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants