Skip to content

Commit 443f93f

Browse files
authored
Merge pull request #1666 from dotty-staging/fix-#1653
Fix #1653: Check "no inherit from final" earlier.
2 parents 6990bb3 + d5656f5 commit 443f93f

File tree

5 files changed

+24
-12
lines changed

5 files changed

+24
-12
lines changed

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,8 @@ class Namer { typer: Typer =>
656656
* (1) It must be a class type with a stable prefix (@see checkClassTypeWithStablePrefix)
657657
* (2) If may not derive from itself
658658
* (3) Overriding type parameters must be correctly forwarded. (@see checkTypeParamOverride)
659+
* (4) The class is not final
660+
* (5) If the class is sealed, it is defined in the same compilation unit as the current class
659661
*/
660662
def checkedParentType(parent: untpd.Tree, paramAccessors: List[Symbol]): Type = {
661663
val ptype = parentType(parent)(ctx.superCallContext)
@@ -674,7 +676,14 @@ class Namer { typer: Typer =>
674676
}
675677
else if (!paramAccessors.forall(checkTypeParamOverride(pt, _)))
676678
defn.ObjectType
677-
else pt
679+
else {
680+
val pclazz = pt.typeSymbol
681+
if (pclazz.is(Final))
682+
ctx.error(em"cannot extend final $pclazz", cls.pos)
683+
if (pclazz.is(Sealed) && pclazz.associatedFile != cls.associatedFile)
684+
ctx.error(em"cannot extend sealed $pclazz in different compilation unit", cls.pos)
685+
pt
686+
}
678687
}
679688
}
680689

src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ object RefChecks {
7272
}
7373
}
7474

75-
/** Check that final and sealed restrictions on class parents
76-
* and that self type of this class conforms to self types of parents.
75+
/** Check that self type of this class conforms to self types of parents.
7776
* and required classes.
7877
*/
7978
private def checkParents(cls: Symbol)(implicit ctx: Context): Unit = cls.info match {
@@ -83,14 +82,8 @@ object RefChecks {
8382
if (otherSelf.exists && !(cinfo.selfType <:< otherSelf))
8483
ctx.error(ex"$category: self type ${cinfo.selfType} of $cls does not conform to self type $otherSelf of $relation ${other.classSymbol}", cls.pos)
8584
}
86-
for (parent <- cinfo.classParents) {
87-
val pclazz = parent.classSymbol
88-
if (pclazz.is(Final))
89-
ctx.error(em"cannot extend final $pclazz", cls.pos)
90-
if (pclazz.is(Sealed) && pclazz.associatedFile != cls.associatedFile)
91-
ctx.error(em"cannot extend sealed $pclazz in different compilation unit", cls.pos)
85+
for (parent <- cinfo.classParents)
9286
checkSelfConforms(parent, "illegal inheritance", "parent")
93-
}
9487
for (reqd <- cinfo.givenSelfType.classSymbols)
9588
checkSelfConforms(reqd.typeRef, "missing requirement", "required")
9689
case _ =>

tests/neg/i1653.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trait Foo {
2+
def foo() = new Unit with Foo // error
3+
}

tests/neg/i705-inner-value-class.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ object Test {
1515
class C(val a: Int) extends AnyVal // error: value class may not be a local class
1616
new C(1)
1717
}
18-
class B1(val b: Int) extends B(b) // error: cannot extend final class B
19-
// class D extends B( { class E(val a: Int) extends AnyVal; new E(1) } )
2018
}
2119

2220

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Foo {
2+
class B(val a: Int) extends AnyVal
3+
}
4+
5+
object Test {
6+
class B1(val b: Int) extends B(b) // error: cannot extend final class B
7+
}
8+
9+

0 commit comments

Comments
 (0)