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

Reflection's path dependent TypeRepr loses information about the prefix when converting to symbol #19933

Open
jchyb opened this issue Mar 12, 2024 · 0 comments
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:bug

Comments

@jchyb
Copy link
Contributor

jchyb commented Mar 12, 2024

Compiler version

If you're not sure what version you're using, run print scalaVersion from sbt
(if you're running scalac manually, use scalac -version instead).

Minimized code

Macro.scala:

import scala.quoted._

inline def pdTypeMacro[T]: Unit = ${ pdTypeMacroImpl[T] }

def pdTypeMacroImpl[T](using quotes: Quotes, tpe: Type[T]): Expr[Unit] =
  import quotes.reflect.*
  val sym = TypeRepr.of[T].classSymbol.get
  println(sym.typeRef) // TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class Outer)),class Inner)
  val mod = Ref(sym.companionModule)
  '{
    ${mod.asExpr}
    ???
  }

Main.scala:

class Outer:
  case class Inner(a: String = "test", b: Int = 23)

object Test:
  def main(args: Array[String]): Unit =
    val outer = Outer()
    pdTypeMacro[outer.Inner]

Output

WIth -Xcheck-macros

-- Error: main.scala:7:15 ------------------------------------------------------
7 |    pdTypeMacro[outer.Inner]
  |    ^^^^^^^^^^^^^^^^^^^^^^^^
  |Malformed tree was found while expanding macro with -Xcheck-macros.
  |The tree does not conform to the compiler's tree invariants.
  |
  |Macro was:
  |scala.quoted.runtime.Expr.splice[scala.Unit](((contextual$1: scala.quoted.Quotes) ?=> macro$package.pdTypeMacroImpl[outer.Inner](contextual$1, scala.quoted.Type.of[outer.Inner](contextual$1))))
  |
  |The macro returned:
  |{
  |  Outer.this.Inner
  |  scala.Predef.???
  |}
  |
  |Error:
  |assertion failed: error while typing Outer.this, method main is not contained in class Outer
  |
  |stacktrace available when compiling with `-Ydebug`
  |-----------------------------------------------------------------------------
  |Inline stack trace
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |This location contains code that was inlined from macro.scala:3
3 |inline def pdTypeMacro[T]: Unit = ${ pdTypeMacroImpl[T] }
  |                                  ^^^^^^^^^^^^^^^^^^^^^^^
   -----------------------------------------------------------------------------

Without:

  exception while retyping Outer.this of class This # -1

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/scala/scala3/issues/new/choose
  For non-enriched exceptions, compile with -Yno-enrich-error-messages.

     while compiling: main.scala
        during phase: MegaPhase{elimErasedValueType, pureStats, vcElideAllocations, etaReduce, arrayApply, elimPolyFunction, tailrec, completeJavaEnums, mixin, lazyVals, memoize, nonLocalReturns, capturedVars}
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.12
    compiler version: version 3.4.2-RC1-bin-SNAPSHOT-nonbootstrapped-git-3694d95
            settings: -classpath /Users/jchyb/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.12/scala-library-2.13.12.jar:/Users/jchyb/Documents/workspace/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.4.2-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.4.2-RC1-bin-SNAPSHOT.jar
Exception in thread "main" 
  Exception while compiling macro.scala, main.scala

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/scala/scala3/issues/new/choose
  For non-enriched exceptions, compile with -Yno-enrich-error-messages.

     while compiling: <no file>
        during phase: parser
                mode: Mode()
     library version: version 2.13.12
    compiler version: version 3.4.2-RC1-bin-SNAPSHOT-nonbootstrapped-git-3694d95
            settings: -classpath /Users/jchyb/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.12/scala-library-2.13.12.jar:/Users/jchyb/Documents/workspace/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.4.2-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.4.2-RC1-bin-SNAPSHOT.jar
java.lang.AssertionError: assertion failed: missing outer accessor in object Test
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
        at dotty.tools.dotc.transform.ExplicitOuter$.dotty$tools$dotc$transform$ExplicitOuter$$$outerParamAccessor(ExplicitOuter.scala:237)
        at dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.loop$1(ExplicitOuter.scala:474)
        at dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.path$extension(ExplicitOuter.scala:483)
        at dotty.tools.dotc.transform.Erasure$Typer.typedThis(Erasure.scala:804)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3124)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3281)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:671)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3098)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3206)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:100)
        at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:904)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3146)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3337)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3356)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1073)
        at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1197)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1201)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3131)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:100)
        at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:904)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3146)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.transform.Erasure$Typer.typedTyped(Erasure.scala:627)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3128)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3281)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:100)
        at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:904)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3146)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3399)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1204)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3131)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3399)
        at dotty.tools.dotc.typer.Typer.$anonfun$63(Typer.scala:2613)
        at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
        at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2613)
        at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:960)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3105)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3206)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3310)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3356)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1073)
        at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2800)
        at dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1049)
        at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3111)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3115)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3206)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3310)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3356)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1073)
        at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2933)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3157)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3207)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:174)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3284)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3288)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3399)
        at dotty.tools.dotc.transform.Erasure.run(Erasure.scala:144)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:354)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:360)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:315)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:337)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:350)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:360)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:360)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:267)
        at dotty.tools.dotc.Run.compileSuspendedUnits(Run.scala:371)
        at dotty.tools.dotc.Driver.finish(Driver.scala:57)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
        at dotty.tools.dotc.Driver.process(Driver.scala:196)
        at dotty.tools.dotc.Driver.process(Driver.scala:164)
        at dotty.tools.dotc.Driver.process(Driver.scala:176)
        at dotty.tools.dotc.Driver.main(Driver.scala:206)
        at dotty.tools.dotc.Main.main(Main.scala)
## Expectation This is not a high priority, as this is caught by `-Xcheck-macros` after all, but I would expect Symbols to represent more correct information about the types. As it is now, any path dependent types like `outer.Inner` effectively become Outer.this.Inner, which is incorrect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:reflection Issues related to the quotes reflection API itype:bug
Projects
None yet
Development

No branches or pull requests

1 participant