Skip to content

Macro dependencies are tracked incorrectly in some cases #16420

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
makkarpov opened this issue Nov 27, 2022 · 2 comments · Fixed by #16426
Closed

Macro dependencies are tracked incorrectly in some cases #16420

makkarpov opened this issue Nov 27, 2022 · 2 comments · Fixed by #16426
Assignees
Labels
area:metaprogramming:quotes Issues related to quotes and splices itype:bug

Comments

@makkarpov
Copy link

Compiler version

3.2.0

Minimized code

Bug reproduces only when two files are in different source sets (i.e. Directive is in main and Meow is in test).

SBT project that reproduces this problem is prepared here. Clone it and do sbt root/test:compile.

directive.scala:

import scala.quoted.{Expr, Quotes, Type}

object Converter {
  private def handleUnit[R](f: Expr[Int ?=> R])(using q: Quotes, rt: Type[R]): Expr[Unit] = ???

  class UnitConverter[R] extends Converter[EmptyTuple, R, Int ?=> R] {
    inline def convert(inline f: Int ?=> R): Unit = ${ handleUnit[R]('f) }
  }

  inline given unitHandler[R]: UnitConverter[R] = new UnitConverter[R]
}


trait Converter[T <: Tuple, R, F] {
  inline def convert(inline fn: F): Unit
}

abstract class Directive[R <: Tuple] {
  inline def apply[O, F](using inline c: Converter[R, O, F])(inline fn: F): Unit =
    c.convert(fn)
}

meow.scala:

object Meow extends App {
  case class Meow(s: String, i: Int)
  
  val dir: Directive[EmptyTuple] = ???
  dir {
    Meow("asd", 123)
  }
}

Output

[error] -- Error: Meow.scala:5:6 
[error]  5 |  dir {
[error]    |  ^
[error]    |  Cannot call macro class Meow defined in the same source file
[error]  6 |    Meow("asd", 123)
[error]  7 |  }
[error]    |----------------------------------------------------------------------------
[error]    |Inline stack trace
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Directive.scala:20
[error] 20 |    c.convert(fn)
[error]    |    ^^^^^^^^^^^^^
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Directive.scala:20
[error] 20 |    c.convert(fn)
[error]    |    ^^^^^^^^^^^^^
[error]     ----------------------------------------------------------------------------

In other circumstances, it does not fails with "Cannot call macro class ... defined in same source file", but fails with "Cyclic macro dependencies in Meow.scala", implying that Meow depends on itself.

Expectation

Code should compile and run

@makkarpov makkarpov added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Nov 27, 2022
@makkarpov
Copy link
Author

makkarpov commented Nov 27, 2022

Compiler marks 'Meow' as dependency due to that Ident(R) in tree:

Trees

Raw AST:

Block(List(DefDef($anonfun,List(List(ValDef(evidence$1,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object quoted),Quotes)],EmptyTree))),TypeTree[AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object quoted),Expr),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Unit)))],Apply(Apply(TypeApply(Ident(inline$handleUnit),List(Ident(R))),List(Apply(Select(Apply(TypeApply(Ident(quote),List(TypeTree[AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),ContextFunction1),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Int), TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class Meow)))])),List(Block(List(DefDef($anonfun,List(List(ValDef(evidence$2,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Int)],EmptyTree))),TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class Meow)],Inlined(EmptyTree,List(),Inlined(EmptyTree,List(),Block(List(),Block(List(),Apply(Select(Ident(Meow),apply),List(Literal(Constant(asd)), Literal(Constant(123)))))))))),Closure(List(),Ident($anonfun),EmptyTree)))),apply),List(Ident(evidence$1))))),List(Ident(evidence$1), Apply(TypeApply(Ident(of),List(TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class Meow)])),List(Ident(evidence$1))))))),Closure(List(),Ident($anonfun),EmptyTree))

Code:

(using evidence$1: quoted.Quotes) => 
  Converter.inline$handleUnit[Meow.Meow](
    '{(using evidence$2: Int) => 
      {
        {
          Meow.Meow.apply("asd", 123)
        }
      }
    }.apply(evidence$1)
  )(evidence$1, quoted.Type.of[Meow.Meow](evidence$1))

Note, however, that R isn't appearing anywhere in decompiled code. Is that R an original issue (i.e. should it be here?)


When issue does not reproduce (with same code), trees look a bit different:

Trees

Raw AST:

Block(List(DefDef($anonfun,List(List(ValDef(evidence$1,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object quoted),Quotes)],EmptyTree))),TypeTree[AppliedType(TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),object quoted),class Expr),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class Unit)))],Apply(Apply(TypeApply(Ident(inline$handleUnit),List(TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class MeowX)])),List(Apply(Select(Apply(TypeApply(Ident(quote),List(TypeTree[AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),trait ContextFunction1),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class Int), TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class MeowX)))])),List(Block(List(DefDef($anonfun,List(List(ValDef(evidence$2,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class Int)],EmptyTree))),TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class MeowX)],Inlined(EmptyTree,List(),Inlined(EmptyTree,List(),Block(List(),Block(List(),Apply(Select(Ident(MeowX),apply),List(Literal(Constant(asd)), Literal(Constant(123)))))))))),Closure(List(),Ident($anonfun),EmptyTree)))),apply),List(Ident(evidence$1))))),List(Ident(evidence$1), Apply(TypeApply(Ident(of),List(TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class MeowX)])),List(Ident(evidence$1))))))),Closure(List(),Ident($anonfun),EmptyTree))

(decompiled code is same)

Note that Ident(R) was replaced by real type tree:

Breaks:

TypeApply(Ident(inline$handleUnit),List(Ident(R))),List(...

Works:

TypeApply(Ident(inline$handleUnit),List(TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Meow$)),class MeowX)])),List(...

@nicolasstucki nicolasstucki added area:metaprogramming:quotes Issues related to quotes and splices and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Nov 28, 2022
@nicolasstucki
Copy link
Contributor

This is already fixed on the main branch. It will work on 3.3.0.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Nov 28, 2022
@nicolasstucki nicolasstucki self-assigned this Nov 28, 2022
nicolasstucki added a commit that referenced this issue Nov 28, 2022
little-inferno pushed a commit to little-inferno/dotty that referenced this issue Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:quotes Issues related to quotes and splices itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants