diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/RefChecks.scala | 20 | ||||
-rw-r--r-- | test/dotc/tests.scala | 2 | ||||
-rw-r--r-- | tests/neg/selfInheritance.scala | 4 |
3 files changed, 18 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala index bb22e2045..71fba1588 100644 --- a/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/src/dotty/tools/dotc/typer/RefChecks.scala @@ -73,19 +73,25 @@ object RefChecks { /** Check that final and sealed restrictions on class parents * and that self type of this class conforms to self types of parents. + * and required classes. */ - private def checkParents(clazz: Symbol)(implicit ctx: Context): Unit = clazz.info match { + private def checkParents(cls: Symbol)(implicit ctx: Context): Unit = cls.info match { case cinfo: ClassInfo => + def checkSelfConforms(other: TypeRef, category: String, relation: String) = { + val otherSelf = other.givenSelfType.asSeenFrom(cls.thisType, other.classSymbol) + if (otherSelf.exists && !(cinfo.selfType <:< otherSelf)) + ctx.error(d"$category: self type ${cinfo.selfType} of $cls does not conform to self type $otherSelf of $relation ${other.classSymbol}", cls.pos) + } for (parent <- cinfo.classParents) { val pclazz = parent.classSymbol if (pclazz.is(Final)) - ctx.error(d"cannot extend final $pclazz", clazz.pos) - if (pclazz.is(Sealed) && pclazz.associatedFile != clazz.associatedFile) - ctx.error(d"cannot extend sealed $pclazz in different compilation unit", clazz.pos) - val pself = parent.givenSelfType.asSeenFrom(clazz.thisType, parent.classSymbol) - if (pself.exists && !(cinfo.selfType <:< pself)) - ctx.error(d"illegal inheritance: self type ${cinfo.selfType} of $clazz does not conform to self type $pself of parent ${parent.classSymbol}", clazz.pos) + ctx.error(d"cannot extend final $pclazz", cls.pos) + if (pclazz.is(Sealed) && pclazz.associatedFile != cls.associatedFile) + ctx.error(d"cannot extend sealed $pclazz in different compilation unit", cls.pos) + checkSelfConforms(parent, "illegal inheritance", "parent") } + for (reqd <- cinfo.givenSelfType.classSymbols) + checkSelfConforms(reqd.typeRef, "missing requirement", "required") case _ => } diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index ee7b93297..3bce26253 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -138,7 +138,7 @@ class tests extends CompilerTest { @Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4) @Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2) @Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8) - @Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 5) + @Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 6) @Test def neg_selfreq = compileFile(negDir, "selfreq", xerrors = 4) @Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2) @Test def neg_traitParamsTyper = compileFile(negDir, "traitParamsTyper", xerrors = 5) diff --git a/tests/neg/selfInheritance.scala b/tests/neg/selfInheritance.scala index 5f61c5bbb..993765817 100644 --- a/tests/neg/selfInheritance.scala +++ b/tests/neg/selfInheritance.scala @@ -26,3 +26,7 @@ object Test { object M extends C // error } + +trait X { self: Y => } +trait Y { self: Z => } +trait Z |