From 0758156d9594d6d3053c158ca3a99a901d6df7ea Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 30 Oct 2023 10:22:48 +0100 Subject: [PATCH] Allow inner classes of universal traits Just forbid inner objects. This aligns with Scala 2 and allows us to keep Seq's definition as in Scala 2. --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 4 +--- tests/neg/inner-classes-of-universal-traits.scala | 8 ++++++++ tests/pos-special/stdlib/collection/IndexedSeq.scala | 2 +- tests/pos-special/stdlib/collection/Seq.scala | 8 +------- 4 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 tests/neg/inner-classes-of-universal-traits.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 6a726432a4b0..ca7089897a47 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2785,11 +2785,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer checkDerivedValueClass(cls, body1) val effectiveOwner = cls.owner.skipWeakOwner - if !cls.isRefinementClass - && !cls.isAllOf(PrivateLocal) + if cls.is(ModuleClass) && effectiveOwner.is(Trait) && !effectiveOwner.derivesFrom(defn.ObjectClass) - && !ctx.settings.YcompileScala2Library.value // FIXME?: class PermutationsItr cannot be defined in universal trait SeqOps then report.error(em"$cls cannot be defined in universal $effectiveOwner", cdef.srcPos) diff --git a/tests/neg/inner-classes-of-universal-traits.scala b/tests/neg/inner-classes-of-universal-traits.scala new file mode 100644 index 000000000000..4988f7b8740d --- /dev/null +++ b/tests/neg/inner-classes-of-universal-traits.scala @@ -0,0 +1,8 @@ +trait Outer extends Any { + trait Inner1 + trait Inner2 extends Any + class Inner3 + class Inner4(a: Int) extends AnyVal // error + case class Inner5(a: Int) // error + object Inner6 // error +} diff --git a/tests/pos-special/stdlib/collection/IndexedSeq.scala b/tests/pos-special/stdlib/collection/IndexedSeq.scala index c48dc4932e62..6e8e2bd0dc66 100644 --- a/tests/pos-special/stdlib/collection/IndexedSeq.scala +++ b/tests/pos-special/stdlib/collection/IndexedSeq.scala @@ -33,7 +33,7 @@ trait IndexedSeq[+A] extends Seq[A] object IndexedSeq extends SeqFactory.Delegate[IndexedSeq](immutable.IndexedSeq) /** Base trait for indexed Seq operations */ -trait IndexedSeqOps[+A, +CC[_], +C] extends AnyRef with SeqOps[A, CC, C] { self => +trait IndexedSeqOps[+A, +CC[_], +C] extends Any with SeqOps[A, CC, C] { self => def iterator: Iterator[A] = view.iterator diff --git a/tests/pos-special/stdlib/collection/Seq.scala b/tests/pos-special/stdlib/collection/Seq.scala index 14a276cfa579..caabf6fa6436 100644 --- a/tests/pos-special/stdlib/collection/Seq.scala +++ b/tests/pos-special/stdlib/collection/Seq.scala @@ -77,13 +77,7 @@ object Seq extends SeqFactory.Delegate[Seq](immutable.Seq) * @define coll sequence * @define Coll `Seq` */ -trait SeqOps[+A, +CC[_], +C] extends AnyRef - // CC TODO: Our treechecker disallows classes in universal traits, but the typer accepts - // them. Since SeqOps contains nested classes, I changed it to be no longer a universal trait. - // Alternatively we could - // - Change TreeChecker to accept this - // - Move nested classes out of the trait - with IterableOps[A, CC, C] { self => +trait SeqOps[+A, +CC[_], +C] extends Any with IterableOps[A, CC, C] { self => override def view: SeqView[A] = new SeqView.Id[A](this)