@@ -1076,6 +1076,7 @@ object Denotations {
10761076 def aggregate [T ](f : SingleDenotation => T , g : (T , T ) => T ): T = f(this )
10771077
10781078 type AsSeenFromResult = SingleDenotation
1079+
10791080 protected def computeAsSeenFrom (pre : Type )(using Context ): SingleDenotation = {
10801081 val symbol = this .symbol
10811082 val owner = this match {
@@ -1120,19 +1121,31 @@ object Denotations {
11201121 then this
11211122 else if symbol.isAllOf(ClassTypeParam ) then
11221123 val arg = symbol.typeRef.argForParam(pre, widenAbstract = true )
1123- if arg.exists then
1124- // take the argument bounds, but intersect with the symbols bounds if
1125- // this forces nothing and gives a non-empty type.
1126- val newBounds =
1127- if symbol.isCompleted && ! symbol.info.containsLazyRefs then
1128- val combined @ TypeBounds (lo, hi) = symbol.info.bounds & arg.bounds
1129- if lo frozen_<:< hi then combined
1130- else arg.bounds
1131- else arg.bounds
1132- derivedSingleDenotation(symbol, newBounds, pre)
1124+ if arg.exists
1125+ then derivedSingleDenotation(symbol, normalizedArgBounds(arg.bounds), pre)
11331126 else derived(symbol.info)
11341127 else derived(symbol.info)
11351128 }
1129+
1130+ /** The argument bounds, possibly intersected with the parameter's info TypeBounds,
1131+ * if the latter is not F-bounded and does not refer to other type parameters
1132+ * of the same class, and the intersection is provably nonempty.
1133+ */
1134+ private def normalizedArgBounds (argBounds : TypeBounds )(using Context ): TypeBounds =
1135+ if symbol.isCompleted && ! hasBoundsDependingOnParamsOf(symbol.owner) then
1136+ val combined @ TypeBounds (lo, hi) = symbol.info.bounds & argBounds
1137+ if (lo frozen_<:< hi) then combined
1138+ else argBounds
1139+ else argBounds
1140+
1141+ private def hasBoundsDependingOnParamsOf (cls : Symbol )(using Context ): Boolean =
1142+ val acc = new TypeAccumulator [Boolean ]:
1143+ def apply (x : Boolean , tp : Type ): Boolean = tp match
1144+ case _ : LazyRef => true
1145+ case tp : TypeRef
1146+ if tp.symbol.isAllOf(ClassTypeParam ) && tp.symbol.owner == cls => true
1147+ case _ => foldOver(x, tp)
1148+ acc(false , symbol.info)
11361149 }
11371150
11381151 abstract class NonSymSingleDenotation (symbol : Symbol , initInfo : Type , override val prefix : Type ) extends SingleDenotation (symbol, initInfo) {
0 commit comments