diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 3dfa5225df5b..a0c5c5a87923 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1688,7 +1688,7 @@ object SymDenotations { */ def children(using Context): List[Symbol] = - def completeChildrenIn(owner: Symbol)(using Context) = + def completeChildrenIn(owner: Symbol, recursively: Boolean)(using Context): Unit = // Possible children are: classes extending Scala classes and // Scala or Java enum values that are defined in owner. // If owner is a package, we complete only @@ -1698,20 +1698,28 @@ object SymDenotations { && (!owner.is(Package) || sym.originDenotation.infoOrCompleter.match case _: SymbolLoaders.SecondCompleter => sym.associatedFile == this.symbol.associatedFile - case _ => false) + case _: ClassInfo if recursively && sym.isValidInCurrentRun => + sym.is(Package) || sym.associatedFile == this.symbol.associatedFile + case other => false) if owner.isClass then for c <- owner.info.decls.toList if maybeChild(c) do c.ensureCompleted() + if recursively then completeChildrenIn(c, recursively) end completeChildrenIn if is(Sealed) || isAllOf(JavaEnumTrait) then if !is(ChildrenQueried) then - // Make sure all visible children are completed, so that - // they show up in Child annotations. A possible child is visible if it - // is defined in the same scope as `cls` or in the companion object of `cls`. - completeChildrenIn(owner) - completeChildrenIn(companionClass) + if !is(Enum) then // non-enum sealed class + // Make sure all children are completed, so that + // they show up in Child annotations. + completeChildrenIn(defn.RootClass, recursively = true) + else + // Make sure all visible children are completed, so that + // they show up in Child annotations. A possible child is visible if it + // is defined in the same scope as `cls` or in the companion object of `cls`. + completeChildrenIn(owner, recursively = false) + completeChildrenIn(companionClass, recursively = false) setFlag(ChildrenQueried) annotations.collect { case Annotation.Child(child) => child }.reverse diff --git a/tests/pos/i18484/Macro_1.scala b/tests/pos/i18484/Macro_1.scala new file mode 100644 index 000000000000..64164e7b3e4c --- /dev/null +++ b/tests/pos/i18484/Macro_1.scala @@ -0,0 +1,11 @@ +object Macro { + import scala.quoted.* + + def subtypesImpl[A: Type](using quotes: Quotes): Expr[String] = { + import quotes.reflect.* + val a = TypeRepr.of[A].typeSymbol.children + '{""} + } + + inline def subtypes[A]: String = ${ subtypesImpl[A] } +} diff --git a/tests/pos/i18484/Test_2.scala b/tests/pos/i18484/Test_2.scala new file mode 100644 index 000000000000..ed130b5dcba6 --- /dev/null +++ b/tests/pos/i18484/Test_2.scala @@ -0,0 +1,21 @@ +class Test { + def test(): Unit = { + scala.compiletime.testing.typeCheckErrors("Macro.subtypes[top.inner.Inner.Shape]") + } +} + +package top { + package inner { + object Inner: + sealed trait Shape + case class Circle(center: Int, rad: Double) extends Shape + object Inner2: + case class Circle2(center: Int, rad: Double) extends Shape + } + case class Circle3(center: Int, rad: Double) extends inner.Inner.Shape +} +case class Circle4(center: Int, rad: Double) extends top.inner.Inner.Shape + +package top2 { + case class Circle5(center: Int, rad: Double) extends top.inner.Inner.Shape +}