@@ -2004,8 +2004,34 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20042004 wrongNumberOfTypeArgs(tpt1.tpe, tparams, args, tree.srcPos)
20052005 args = args.take(tparams.length)
20062006 }
2007+
2008+ // If type constructor is not a class type, we need to eliminate
2009+ // any references to other parameter types of the underlying hk lambda
2010+ // in order not to get orphan parameters. Test case in pos/i15564.scala.
2011+ // Note 1: It would be better to substitute actual arguments for corresponding
2012+ // formal paramaters, but it looks very hard to do this at the point where
2013+ // a bound type variable is created.
2014+ // Note 2: If the type constructor is a class type, no sanitization is needed
2015+ // since we can refer to the other paraeters with dependent types C[...]#X.
2016+ def sanitizeBounds (bounds : Type , tycon : Type ): Type =
2017+ def underlyingLambda (tp : Type ): Type = tp match
2018+ case tp : HKTypeLambda => tp
2019+ case tp : TypeProxy => underlyingLambda(tp.superType)
2020+ case _ => NoType
2021+ val tl = underlyingLambda(tycon)
2022+ val widenMap = new TypeOps .AvoidMap :
2023+ def toAvoid (tp : NamedType ) = false
2024+ override def apply (tp : Type ): Type = tp match
2025+ case tp : TypeParamRef if tp.binder == tl => emptyRange
2026+ case _ => super .apply(tp)
2027+ widenMap(bounds)
2028+
20072029 def typedArg (arg : untpd.Tree , tparam : ParamInfo ) = {
2008- def tparamBounds = tparam.paramInfoAsSeenFrom(tpt1.tpe.appliedTo(tparams.map(_ => TypeBounds .empty)))
2030+ def tparamBounds =
2031+ val bounds =
2032+ tparam.paramInfoAsSeenFrom(tpt1.tpe.appliedTo(tparams.map(_ => TypeBounds .empty)))
2033+ if tparam.isInstanceOf [Symbol ] then bounds
2034+ else sanitizeBounds(bounds, tpt1.tpe)
20092035 val (desugaredArg, argPt) =
20102036 if ctx.mode.is(Mode .Pattern ) then
20112037 (if (untpd.isVarPattern(arg)) desugar.patternVar(arg) else arg, tparamBounds)
0 commit comments