scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

runtime/compile time reflection doesn't see all knownDirectSubclasses #7046

Closed scabug closed 7 years ago

scabug commented 11 years ago

Unlike, say, annotations or flags, knownDirectSubclasses doesn't get auto-populated and requires a symbol to be pre-initialized to work correctly.

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}

sealed class C
class D extends C
class E extends C

object Test extends App {
  val c = cm.staticClass("C")
  println(c.knownDirectSubclasses)
  c.typeSignature
  println(c.knownDirectSubclasses)
}
19:43 ~/Projects/Kepler_7046/sandbox (ticket/7046)$ scalac Test.scala && scala Test
Set()
Set(class D, class E)
scabug commented 11 years ago

Imported From: https://issues.scala-lang.org/browse/SI-7046?orig=1 Reporter: @xeno-by Affected Versions: 2.10.0, 2.11.0 Other Milestones: 2.12.1

scabug commented 11 years ago

@xeno-by said: Probably should a very easy fix. Will try to get it once we're discussing synchronization.

scabug commented 11 years ago

@xeno-by said: https://github.com/scala/scala/pull/2039

scabug commented 11 years ago

@xeno-by said: Fixed in https://github.com/scala/scala/commit/2403d1ddcaa1bd76c1f376a32ec03a36d4dab48b

scabug commented 11 years ago

@adriaanm said: Actually, this only works when you query knownDirectSubclasses after those trees have been typed, so macros that occur before the class C in your example has been type checked won't see its subclasses.

scabug commented 11 years ago

@JamesIry said: 2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.

scabug commented 11 years ago

@retronym said: Test case for compile time reflection in #7588

scabug commented 10 years ago

Valentin Churavy (wallnuss) said (edited on Dec 10, 2013 6:46:40 AM UTC): I still run into this on 2.10.3 and the work around with calling c.typeSignature before c.knownDirectSubclasses doesn't work for the reason Adriaan noticed. Forcing a recompile on only the parts which use the macro solve this error, but that is of course not really satisfactory.

scabug commented 10 years ago

@adriaanm said: Sorry, this is not something we can fix due the way the typechecker is implemented. The "fix" would be to remove this method from the reflection API.

scabug commented 10 years ago

Valentin Churavy (wallnuss) said: Would it be possible to reschedule the classes where the macro is used for compilation after the TypeCheck has occurred?

scabug commented 10 years ago

@xeno-by said: Discussion: https://groups.google.com/forum/#!topic/scala-internals/LRfKffsPxVA

scabug commented 10 years ago

@xeno-by said: Actually, I think we can fix this for an important subset of macros: https://groups.google.com/forum/#!topic/scala-user/oJP9aqs88rM

scabug commented 10 years ago

@xeno-by said: See another test case at #8776

scabug commented 8 years ago

@milessabin said: @adriaanm can you elaborate on "this is not something we can fix due the way the typechecker is implemented" ... are there any specific obstacles you have in mind?

scabug commented 8 years ago

@Blaisorblade said: 1) Since this is a design issue, do scala.meta and/or Dotty change things here? I wonder if we need a label like redesign for such issues. 2) @milessabin the design issue is mentioned in the discussion links, in particular in https://groups.google.com/d/msg/scala-internals/LRfKffsPxVA/db_jmsa7FO4J:

knownDirectSubclasses relies on a full top-down pass having been completed before you call it.

Technically, we could provide a onTypecheckCompilationUnit that you could use, but this isn't currently planned for the macro api (well, I'll let Eugene comment on that, but I'm not aware of any plans here -- in any case, 2.11 is in ramp down)

scabug commented 8 years ago

@xeno-by said: Scala.meta relies on the underlying platform typechecker, so it won't change anything here unless the implementation of scalac/dotc changes.

One way to fix this issue without changing the typechecker is to move macro expansion to after typer instead of during typer. We'll have to experiment with this, because there are some technical difficulties with implementing that (e.g. implicit inference not working well after typer, etc).

scabug commented 8 years ago

@milessabin said: WIP PR here: https://github.com/scala/scala/pull/5284

scabug commented 8 years ago

@cchantep said: Could the following be used as workaround in some case (seems to work in my case as far as I can see).

val cls: ClassSymbol = sub.asClass

println(s"knownDirectSubclasses = ${cls.knownDirectSubclasses}")
// print "knownDirectSubclasses = Set()"

val subsub = cls.owner.typeSignature.decls.filter {
  case c: ClassSymbol =>
    cls != c && c.selfType.baseClasses.contains(cls)

  case _ => false
}

println(s"subsub = $subsub")
// print the actual sub classes
scabug commented 8 years ago

@milessabin said: Fix backported to 2.11.8 is available here.

scabug commented 8 years ago

@adriaanm said: https://github.com/scala/scala/pull/5345

scabug commented 7 years ago

@adriaanm said: To track future refinements, please open a new issue. Closing this one to mark our progress.