File tree 3 files changed +49
-1
lines changed
compiler/src/dotty/tools/dotc/typer
3 files changed +49
-1
lines changed Original file line number Diff line number Diff line change @@ -782,7 +782,34 @@ object RefChecks {
782
782
report.error(problem(), clazz.srcPos)
783
783
}
784
784
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
+
785
811
checkParameterizedTraitsOK()
812
+ checkTraitParametersOK()
786
813
}
787
814
788
815
/** Check that `site` does not inherit conflicting generic instances of `baseCls`,
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change @@ -3,7 +3,7 @@ object Test extends App {
3
3
class B [+ X ](val y : X ) extends A [X ](y)
4
4
class C extends B (5 ) with A [String ] // error: illegal inheritance
5
5
6
- class D extends B (5 ) with A [Any ] // ok
6
+ class D extends B (5 ) with A [Any ] // error: illegal parameter
7
7
8
8
def f (a : A [Int ]): String = a match {
9
9
case c : C => c.x
You can’t perform that action at this time.
0 commit comments