@@ -157,28 +157,35 @@ object ProtoTypes {
157
157
abstract case class SelectionProto (name : Name , memberProto : Type , compat : Compatibility , privateOK : Boolean )
158
158
extends CachedProxyType with ProtoType with ValueTypeOrProto {
159
159
160
- /** Is the set of members of this type unknown? This is the case if:
161
- * 1. The type has Nothing or Wildcard as a prefix or underlying type
162
- * 2. The type has an uninstantiated TypeVar as a prefix or underlying type,
163
- * or as an upper bound of a prefix or underlying type.
160
+ /** Is the set of members of this type unknown, in the sense that we
161
+ * cannot compute a non-trivial upper approximation? This is the case if:
162
+ * 1. The type has Nothing or Wildcard as a prefix or underlying type
163
+ * 2. The type is an abstract type with a lower bound that has a unknown
164
+ * members and an upper bound that is both provisional and has unknown members.
165
+ * 3. The type is an uninstiated type var with a lower that has unknown members.
166
+ * 4. Type proxies have unknown members if their super types do
164
167
*/
165
- private def hasUnknownMembers (tp : Type )(using Context ): Boolean = tp match {
166
- case tp : TypeVar => ! tp.isInstantiated
168
+ private def hasUnknownMembers (tp : Type )(using Context ): Boolean = tp match
167
169
case tp : WildcardType => true
168
170
case NoType => true
169
171
case tp : TypeRef =>
170
172
val sym = tp.symbol
171
- sym == defn.NothingClass ||
172
- ! sym.isStatic && {
173
- hasUnknownMembers(tp.prefix) || {
174
- val bound = tp.info.hiBound
175
- bound.isProvisional && hasUnknownMembers(bound)
176
- }
177
- }
173
+ sym == defn.NothingClass
174
+ || ! sym.isClass
175
+ && ! sym.isStatic
176
+ && {
177
+ hasUnknownMembers(tp.prefix)
178
+ || { val bound = tp.info.hiBound
179
+ bound.isProvisional && hasUnknownMembers(bound)
180
+ } && hasUnknownMembers(tp.info.loBound)
181
+ }
182
+ case tp : TypeVar if ! tp.isInstantiated =>
183
+ hasUnknownMembers(TypeComparer .bounds(tp.origin).lo)
178
184
case tp : AppliedType => hasUnknownMembers(tp.tycon) || hasUnknownMembers(tp.superType)
179
185
case tp : TypeProxy => hasUnknownMembers(tp.superType)
186
+ // It woukd make sense to also include And/OrTypes, but that leads to
187
+ // infinite recursions, as observed for instance for t2399.scala.
180
188
case _ => false
181
- }
182
189
183
190
override def isMatchedBy (tp1 : Type , keepConstraint : Boolean )(using Context ): Boolean =
184
191
name == nme.WILDCARD || hasUnknownMembers(tp1) ||
0 commit comments