@@ -433,6 +433,10 @@ object Types {
433433 /** Is this a higher-kinded type lambda with given parameter variances? */
434434 def isDeclaredVarianceLambda : Boolean = false
435435
436+ /** Does this type contain wildcard types? */
437+ final def containsWildcardTypes (using Context ) =
438+ existsPart(_.isInstanceOf [WildcardType ], stopAtStatic = true )
439+
436440// ----- Higher-order combinators -----------------------------------
437441
438442 /** Returns true if there is a part of this type that satisfies predicate `p`.
@@ -4465,13 +4469,30 @@ object Types {
44654469 def instantiate (fromBelow : Boolean )(using Context ): Type =
44664470 instantiateWith(avoidCaptures(TypeComparer .instanceType(origin, fromBelow)))
44674471
4472+ /** For uninstantiated type variables: the entry in the constraint (either bounds or
4473+ * provisional instance value)
4474+ */
4475+ private def currentEntry (using Context ): Type = ctx.typerState.constraint.entry(origin)
4476+
44684477 /** For uninstantiated type variables: Is the lower bound different from Nothing? */
4469- def hasLowerBound (using Context ): Boolean =
4470- ! ctx.typerState.constraint.entry(origin).loBound.isExactlyNothing
4478+ def hasLowerBound (using Context ): Boolean = ! currentEntry.loBound.isExactlyNothing
44714479
44724480 /** For uninstantiated type variables: Is the upper bound different from Any? */
4473- def hasUpperBound (using Context ): Boolean =
4474- ! ctx.typerState.constraint.entry(origin).hiBound.isRef(defn.AnyClass )
4481+ def hasUpperBound (using Context ): Boolean = ! currentEntry.hiBound.isRef(defn.AnyClass )
4482+
4483+ /** For uninstantiated type variables: Is the lower bound different from Nothing and
4484+ * does it not contain wildcard types?
4485+ */
4486+ def hasNonWildcardLowerBound (using Context ): Boolean =
4487+ val lo = currentEntry.loBound
4488+ ! lo.isExactlyNothing && ! lo.containsWildcardTypes
4489+
4490+ /** For uninstantiated type variables: Is the upper bound different from Any and
4491+ * does it not contain wildcard types?
4492+ */
4493+ def hasNonWildcardUpperBound (using Context ): Boolean =
4494+ val hi = currentEntry.hiBound
4495+ ! hi.isRef(defn.AnyClass ) && ! hi.containsWildcardTypes
44754496
44764497 /** Unwrap to instance (if instantiated) or origin (if not), until result
44774498 * is no longer a TypeVar
0 commit comments