diff options
author | odersky <odersky@gmail.com> | 2016-11-16 14:54:27 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-16 14:54:27 +0100 |
commit | 443f93f38e3e4bbc346ff945eb0fa51939f3d3a9 (patch) | |
tree | 53460dd13c2026f5a02f0567db0cec4d47261ca5 | |
parent | 6990bb37ee070ad4ffea21eb7557c4b438f1b295 (diff) | |
parent | d5656f51972f6a8cc122f47abf144bee29fcf022 (diff) | |
download | dotty-443f93f38e3e4bbc346ff945eb0fa51939f3d3a9.tar.gz dotty-443f93f38e3e4bbc346ff945eb0fa51939f3d3a9.tar.bz2 dotty-443f93f38e3e4bbc346ff945eb0fa51939f3d3a9.zip |
Merge pull request #1666 from dotty-staging/fix-#1653
Fix #1653: Check "no inherit from final" earlier.
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/RefChecks.scala | 11 | ||||
-rw-r--r-- | tests/neg/i1653.scala | 3 | ||||
-rw-r--r-- | tests/neg/i705-inner-value-class.scala | 2 | ||||
-rw-r--r-- | tests/neg/i705-inner-value-class2.scala | 9 |
5 files changed, 24 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index dd7326fae..687de1e7a 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -656,6 +656,8 @@ class Namer { typer: Typer => * (1) It must be a class type with a stable prefix (@see checkClassTypeWithStablePrefix) * (2) If may not derive from itself * (3) Overriding type parameters must be correctly forwarded. (@see checkTypeParamOverride) + * (4) The class is not final + * (5) If the class is sealed, it is defined in the same compilation unit as the current class */ def checkedParentType(parent: untpd.Tree, paramAccessors: List[Symbol]): Type = { val ptype = parentType(parent)(ctx.superCallContext) @@ -674,7 +676,14 @@ class Namer { typer: Typer => } else if (!paramAccessors.forall(checkTypeParamOverride(pt, _))) defn.ObjectType - else pt + else { + val pclazz = pt.typeSymbol + if (pclazz.is(Final)) + ctx.error(em"cannot extend final $pclazz", cls.pos) + if (pclazz.is(Sealed) && pclazz.associatedFile != cls.associatedFile) + ctx.error(em"cannot extend sealed $pclazz in different compilation unit", cls.pos) + pt + } } } diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala index 026015d1d..46bdbf3b3 100644 --- a/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/src/dotty/tools/dotc/typer/RefChecks.scala @@ -72,8 +72,7 @@ object RefChecks { } } - /** Check that final and sealed restrictions on class parents - * and that self type of this class conforms to self types of parents. + /** Check that self type of this class conforms to self types of parents. * and required classes. */ private def checkParents(cls: Symbol)(implicit ctx: Context): Unit = cls.info match { @@ -83,14 +82,8 @@ object RefChecks { if (otherSelf.exists && !(cinfo.selfType <:< otherSelf)) ctx.error(ex"$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(em"cannot extend final $pclazz", cls.pos) - if (pclazz.is(Sealed) && pclazz.associatedFile != cls.associatedFile) - ctx.error(em"cannot extend sealed $pclazz in different compilation unit", cls.pos) + for (parent <- cinfo.classParents) checkSelfConforms(parent, "illegal inheritance", "parent") - } for (reqd <- cinfo.givenSelfType.classSymbols) checkSelfConforms(reqd.typeRef, "missing requirement", "required") case _ => diff --git a/tests/neg/i1653.scala b/tests/neg/i1653.scala new file mode 100644 index 000000000..ab5369e5f --- /dev/null +++ b/tests/neg/i1653.scala @@ -0,0 +1,3 @@ +trait Foo { + def foo() = new Unit with Foo // error +} diff --git a/tests/neg/i705-inner-value-class.scala b/tests/neg/i705-inner-value-class.scala index 82ac962b5..ecef8c5fe 100644 --- a/tests/neg/i705-inner-value-class.scala +++ b/tests/neg/i705-inner-value-class.scala @@ -15,8 +15,6 @@ object Test { class C(val a: Int) extends AnyVal // error: value class may not be a local class new C(1) } - class B1(val b: Int) extends B(b) // error: cannot extend final class B -// class D extends B( { class E(val a: Int) extends AnyVal; new E(1) } ) } diff --git a/tests/neg/i705-inner-value-class2.scala b/tests/neg/i705-inner-value-class2.scala new file mode 100644 index 000000000..a084da338 --- /dev/null +++ b/tests/neg/i705-inner-value-class2.scala @@ -0,0 +1,9 @@ +class Foo { + class B(val a: Int) extends AnyVal +} + +object Test { + class B1(val b: Int) extends B(b) // error: cannot extend final class B +} + + |