@@ -182,6 +182,18 @@ object Types {
182182 loop(this )
183183 }
184184
185+ /** True iff `symd` is a denotation of a class type parameter and the reference
186+ * `<this> . <symd>` is an actual argument reference, i.e. `this` is different
187+ * from the ThisType of `symd`'s owner.
188+ */
189+ def isArgPrefix (symd : SymDenotation )(implicit ctx : Context ) =
190+ Config .newScheme && symd.is(ClassTypeParam ) && {
191+ this match {
192+ case tp : ThisType => tp.cls ne symd.owner
193+ case _ => true
194+ }
195+ }
196+
185197 /** Returns true if the type is a phantom type
186198 * - true if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
187199 * - false otherwise
@@ -1659,6 +1671,8 @@ object Types {
16591671 val symd = sym.lastKnownDenotation
16601672 if (symd.validFor.runId != ctx.runId && ! ctx.stillValid(symd))
16611673 finish(memberDenot(symd.initial.name, allowPrivate = false ))
1674+ else if (prefix.isArgPrefix(symd))
1675+ finish(argDenot(sym.asType))
16621676 else if (infoDependsOnPrefix(symd, prefix))
16631677 finish(memberDenot(symd.initial.name, allowPrivate = symd.is(Private )))
16641678 else
@@ -1715,6 +1729,32 @@ object Types {
17151729 private def memberDenot (prefix : Type , name : Name , allowPrivate : Boolean )(implicit ctx : Context ): Denotation =
17161730 if (allowPrivate) prefix.member(name) else prefix.nonPrivateMember(name)
17171731
1732+ private def argDenot (param : TypeSymbol )(implicit ctx : Context ): Denotation = {
1733+ val cls = param.owner
1734+ val args = prefix.baseType(cls).argInfos
1735+ val typeParams = cls.typeParams
1736+
1737+ def concretize (arg : Type , tparam : TypeSymbol ) = arg match {
1738+ case arg : TypeBounds => TypeRef (prefix, tparam)
1739+ case arg => arg
1740+ }
1741+ val concretized = args.zipWithConserve(typeParams)(concretize)
1742+
1743+ def rebase (arg : Type ) = arg.subst(typeParams, concretized)
1744+
1745+ val idx = typeParams.indexOf(param)
1746+ val argInfo = args(idx) match {
1747+ case arg : TypeBounds =>
1748+ val v = param.paramVariance
1749+ val pbounds = param.paramInfo
1750+ if (v > 0 && pbounds.loBound.dealias.isBottomType) TypeAlias (arg.hiBound & rebase(pbounds.hiBound))
1751+ else if (v < 0 && pbounds.hiBound.dealias.isTopType) TypeAlias (arg.loBound | rebase(pbounds.loBound))
1752+ else arg recoverable_& rebase(pbounds)
1753+ case arg => TypeAlias (arg)
1754+ }
1755+ param.derivedSingleDenotation(param, argInfo)
1756+ }
1757+
17181758 /** Reload denotation by computing the member with the reference's name as seen
17191759 * from the reference's prefix.
17201760 */
@@ -1838,7 +1878,9 @@ object Types {
18381878 while (tparams.nonEmpty && args.nonEmpty) {
18391879 if (tparams.head.eq(tparam))
18401880 return args.head match {
1841- case _ : TypeBounds => TypeArgRef (pre, cls.typeRef, idx)
1881+ case _ : TypeBounds =>
1882+ if (Config .newScheme) TypeRef (pre, tparam)
1883+ else TypeArgRef (pre, cls.typeRef, idx)
18421884 case arg => arg
18431885 }
18441886 tparams = tparams.tail
@@ -1940,7 +1982,7 @@ object Types {
19401982 else if (lastDenotation == null ) NamedType (prefix, designator)
19411983 else designator match {
19421984 case sym : Symbol =>
1943- if (infoDependsOnPrefix(sym, prefix)) {
1985+ if (infoDependsOnPrefix(sym, prefix) && ! prefix.isArgPrefix(sym) ) {
19441986 val candidate = reload()
19451987 val falseOverride = sym.isClass && candidate.symbol.exists && candidate.symbol != symbol
19461988 // A false override happens if we rebind an inner class to another type with the same name
@@ -4026,6 +4068,11 @@ object Types {
40264068 case TypeBounds (lo, hi) => range(atVariance(- variance)(reapply(lo)), reapply(hi))
40274069 case arg => reapply(arg)
40284070 }
4071+ case arg @ TypeRef (pre, _) if pre.isArgPrefix(arg.symbol) =>
4072+ arg.info match {
4073+ case TypeBounds (lo, hi) => range(atVariance(- variance)(reapply(lo)), reapply(hi))
4074+ case arg => reapply(arg)
4075+ }
40294076 case arg => reapply(arg)
40304077 }
40314078 }
0 commit comments