@@ -1076,6 +1076,7 @@ object Denotations {
1076
1076
def aggregate [T ](f : SingleDenotation => T , g : (T , T ) => T ): T = f(this )
1077
1077
1078
1078
type AsSeenFromResult = SingleDenotation
1079
+
1079
1080
protected def computeAsSeenFrom (pre : Type )(using Context ): SingleDenotation = {
1080
1081
val symbol = this .symbol
1081
1082
val owner = this match {
@@ -1120,19 +1121,31 @@ object Denotations {
1120
1121
then this
1121
1122
else if symbol.isAllOf(ClassTypeParam ) then
1122
1123
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)
1133
1126
else derived(symbol.info)
1134
1127
else derived(symbol.info)
1135
1128
}
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)
1136
1149
}
1137
1150
1138
1151
abstract class NonSymSingleDenotation (symbol : Symbol , initInfo : Type , override val prefix : Type ) extends SingleDenotation (symbol, initInfo) {
0 commit comments