Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -488,14 +488,22 @@ class Namer { typer: Typer =>
*/
final def addChild(cls: Symbol, child: Symbol)(using Context): Unit = {
val childStart = if (child.span.exists) child.span.start else -1
// A Child annotation that is currently being forced cannot be safely
// inspected here (forcing it again would trigger an assertion in
// `LazyAnnotation.tree`). This can happen when adding a child causes
// completion of another class that itself needs to be added as a child of
// the same parent (see tests/pos-special/i24719). In that case, fall back
// to just prepending the new Child annotation.
def isReady(ann: Annotation): Boolean =
ann.symbol == defn.ChildAnnot && !ann.isEvaluating
def insertInto(annots: List[Annotation]): List[Annotation] =
annots.find(_.symbol == defn.ChildAnnot) match {
annots.find(isReady) match {
case Some(Annotation.Child(other)) if other.span.exists && childStart <= other.span.start =>
if (child == other)
annots // can happen if a class has several inaccessible children
else {
assert(childStart != other.span.start || child.source != other.source, i"duplicate child annotation $child / $other")
val (prefix, otherAnnot :: rest) = annots.span(_.symbol != defn.ChildAnnot): @unchecked
val (prefix, otherAnnot :: rest) = annots.span(ann => !isReady(ann)): @unchecked
prefix ::: otherAnnot :: insertInto(rest)
}
case _ =>
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class CompilationTests {
compileFile("tests/pos-special/utf16encoded.scala", defaultOptions.and("-encoding", "UTF16")),
compileDir("tests/pos-special/i18589", defaultOptions.and("-Wsafe-init").without("-Ycheck:all")),
compileDir("tests/pos-special/i24547", defaultOptions.without("-Ycheck:all")),
compileDir("tests/pos-special/i24719", defaultOptions.without("-Ycheck:all")),
// Run tests for legacy lazy vals
compileFilesInDir("tests/pos", defaultOptions.and("-Wsafe-init", "-Ylegacy-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.posLazyValsAllowlist)),
compileDir("tests/pos-special/java-param-names", defaultOptions.withJavacOnlyOptions("-parameters")),
Expand Down
2 changes: 2 additions & 0 deletions tests/pos-special/i24719/Tuple1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package scala
final case class Tuple1[+T1](_1: T1) extends Product1[T1]
5 changes: 5 additions & 0 deletions tests/pos-special/i24719/Tuple22.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package scala
final case class Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22](
_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11,
_12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21, _22: T22)
extends Product22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]
Loading