@@ -157,28 +157,35 @@ object ProtoTypes {
157157 abstract case class SelectionProto (name : Name , memberProto : Type , compat : Compatibility , privateOK : Boolean )
158158 extends CachedProxyType with ProtoType with ValueTypeOrProto {
159159
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 a type param ref or uninstiated type var with a lower
166+ * that has unknown members.
167+ * 4. Type proxies have unknown members if their super types do
164168 */
165- private def hasUnknownMembers (tp : Type )(using Context ): Boolean = tp match {
166- case tp : TypeVar => ! tp.isInstantiated
169+ private def hasUnknownMembers (tp : Type )(using Context ): Boolean = tp match
167170 case tp : WildcardType => true
168171 case NoType => true
169172 case tp : TypeRef =>
170173 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- }
174+ defn.isBottomClass(sym)
175+ || ! sym.isClass
176+ && ! sym.isStatic
177+ && {
178+ hasUnknownMembers(tp.prefix)
179+ || { val bound = tp.info.hiBound
180+ bound.isProvisional && hasUnknownMembers(bound)
181+ } && hasUnknownMembers(tp.info.loBound)
182+ }
183+ case tp : TypeParamRef => hasUnknownMembers(TypeComparer .bounds(tp).lo)
178184 case tp : AppliedType => hasUnknownMembers(tp.tycon) || hasUnknownMembers(tp.superType)
179185 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.
180188 case _ => false
181- }
182189
183190 override def isMatchedBy (tp1 : Type , keepConstraint : Boolean )(using Context ): Boolean =
184191 name == nme.WILDCARD || hasUnknownMembers(tp1) ||
0 commit comments