@@ -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 an uninstiated type var with a lower that has unknown members.
166+ * 4. Type proxies have unknown members if their super types do
164167 */
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
167169 case tp : WildcardType => true
168170 case NoType => true
169171 case tp : TypeRef =>
170172 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)
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