Skip to content

Commit 16a1553

Browse files
committed
Check conformance of trait and class parameters of base types
1 parent 8effbc4 commit 16a1553

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,34 @@ object RefChecks {
782782
report.error(problem(), clazz.srcPos)
783783
}
784784

785+
// check that basetype and subtype agree on types of trait parameters
786+
//
787+
// I.e. trait and class parameters not only need to conform to the expected
788+
// type of the corresponding base-trait, but also to the type as seen by the
789+
// inheriting subtype.
790+
def checkTraitParametersOK() = for {
791+
parent <- clazz.info.parents
792+
parentSym = parent.classSymbol
793+
if parentSym.isClass
794+
cls = parentSym.asClass
795+
if cls.paramAccessors.nonEmpty
796+
param <- cls.paramAccessors
797+
} {
798+
val tpeFromParent = parent.memberInfo(param)
799+
val tpeFromClazz = clazz.thisType.memberInfo(param)
800+
if (!(tpeFromParent <:< tpeFromClazz)) {
801+
val msg =
802+
em"""illegal parameter: The types of $param do not match.
803+
|
804+
| $param in $cls has type: $tpeFromParent
805+
| but $clazz expects $param to have type: $tpeFromClazz"""
806+
807+
report.error(msg, clazz.srcPos)
808+
}
809+
}
810+
785811
checkParameterizedTraitsOK()
812+
checkTraitParametersOK()
786813
}
787814

788815
/** Check that `site` does not inherit conflicting generic instances of `baseCls`,

tests/neg/i11018.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait Foo {
2+
def name: String
3+
}
4+
class Bar
5+
6+
trait CClass[+A](val a: A) {
7+
val b = a
8+
}
9+
10+
trait CTrait[+A](val a: A) {
11+
val b = a
12+
}
13+
trait DTrait[+B] extends CTrait[B]
14+
trait DClass[+B] extends CClass[B]
15+
16+
final class F1 extends DTrait[Foo] with CTrait[Bar](new Bar) // error: illegal parameter
17+
final class F2 extends CTrait[Bar](new Bar) with DTrait[Foo] // error: illegal parameter
18+
final class F3 extends DClass[Foo] with CClass[Bar](new Bar) // error: illegal parameter
19+
final class F4 extends CClass[Bar](new Bar) with DClass[Foo] // error: illegal parameter
20+
21+
final class F5 extends DTrait[Foo] with CTrait[Foo & Bar](new Bar with Foo { def name = "hello"}) // ok

tests/neg/i3989f.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ object Test extends App {
33
class B[+X](val y: X) extends A[X](y)
44
class C extends B(5) with A[String] // error: illegal inheritance
55

6-
class D extends B(5) with A[Any] // ok
6+
class D extends B(5) with A[Any] // error: illegal parameter
77

88
def f(a: A[Int]): String = a match {
99
case c: C => c.x

0 commit comments

Comments
 (0)