From 175499537c87c78d0b926d84b7a9030011e42c00 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 28 Jun 2015 19:33:35 +0200 Subject: Check that a self type T is closed. What is checked: A self type T is a subtype of all selftypes of classes refernced by T. That is, a self type has to subsume all self types of its required type. Ot, otherwise said, requirements must be closed; you cannot discover new ones in following them. --- src/dotty/tools/dotc/typer/RefChecks.scala | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/dotty') 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 _ => } -- cgit v1.2.3