@@ -26,7 +26,7 @@ import Constants.Constant
2626import NullOpsDecorator ._
2727
2828object RefChecks {
29- import tpd .{ Tree , MemberDef , NamedArg , Literal , Template , DefDef }
29+ import tpd ._
3030
3131 val name : String = " refchecks"
3232
@@ -133,6 +133,27 @@ object RefChecks {
133133 false
134134 }
135135
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)
136157 case _ =>
137158 }
138159
@@ -801,34 +822,7 @@ object RefChecks {
801822 report.error(problem(), clazz.srcPos)
802823 }
803824
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-
830825 checkParameterizedTraitsOK()
831- checkTraitParametersOK()
832826 }
833827
834828 /** Check that `site` does not inherit conflicting generic instances of `baseCls`,
0 commit comments