@@ -26,7 +26,7 @@ import Constants.Constant
26
26
import NullOpsDecorator ._
27
27
28
28
object RefChecks {
29
- import tpd .{ Tree , MemberDef , NamedArg , Literal , Template , DefDef }
29
+ import tpd ._
30
30
31
31
val name : String = " refchecks"
32
32
@@ -133,6 +133,27 @@ object RefChecks {
133
133
false
134
134
}
135
135
136
+ /** Check that arguments passed to trait parameters conform to the parameter types
137
+ * in the current class. This is necessary since parameter types might be narrowed
138
+ * through intersection with other parent traits. See neg/i11018.scala.
139
+ */
140
+ def checkParamInits (app : Apply ): Unit =
141
+ val parentCls = app.tpe.classSymbol
142
+ if parentCls.is(Trait ) then
143
+ val params = parentCls.asClass.paramGetters
144
+ val args = termArgss(app).flatten
145
+ for (param, arg) <- params.lazyZip(args) do
146
+ if ! param.is(Private ) then // its type can be narrowed through intersection -> a check is needed
147
+ val paramType = cls.thisType.memberInfo(param)
148
+ if ! (arg.tpe <:< paramType) then
149
+ val argTypes = args.tpes
150
+ // it could still be OK but we might need to substitute arguments for parameters
151
+ // to account for dependent parameters. See pos/i11993.scala
152
+ if ! (arg.tpe.subst(params, argTypes) <:< paramType.subst(params, argTypes))
153
+ then
154
+ report.error(IllegalParameterInit (arg.tpe, paramType, param, cls), arg.srcPos)
155
+
156
+ for case app : Apply <- parentTrees do checkParamInits(app)
136
157
case _ =>
137
158
}
138
159
@@ -801,34 +822,7 @@ object RefChecks {
801
822
report.error(problem(), clazz.srcPos)
802
823
}
803
824
804
- // check that basetype and subtype agree on types of trait parameters
805
- //
806
- // I.e. trait and class parameters not only need to conform to the expected
807
- // type of the corresponding base-trait, but also to the type as seen by the
808
- // inheriting subtype.
809
- def checkTraitParametersOK () = for {
810
- parent <- clazz.info.parents
811
- parentSym = parent.classSymbol
812
- if parentSym.isClass
813
- cls = parentSym.asClass
814
- if cls.paramAccessors.nonEmpty
815
- param <- cls.paramAccessors
816
- } {
817
- val tpeFromParent = parent.memberInfo(param)
818
- val tpeFromClazz = clazz.thisType.memberInfo(param)
819
- if (! (tpeFromParent <:< tpeFromClazz)) {
820
- val msg =
821
- em """ illegal parameter: The types of $param do not match.
822
- |
823
- | $param in $cls has type: $tpeFromParent
824
- | but $clazz expects $param to have type: $tpeFromClazz"""
825
-
826
- report.error(msg, clazz.srcPos)
827
- }
828
- }
829
-
830
825
checkParameterizedTraitsOK()
831
- checkTraitParametersOK()
832
826
}
833
827
834
828
/** Check that `site` does not inherit conflicting generic instances of `baseCls`,
0 commit comments