aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala20
-rw-r--r--test/dotc/tests.scala2
-rw-r--r--tests/neg/selfInheritance.scala4
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