@@ -429,6 +429,10 @@ object Types {
429429 /** Is this a higher-kinded type lambda with given parameter variances? */
430430 def isDeclaredVarianceLambda : Boolean = false
431431
432+ /** Does this type contain wildcard types? */
433+ final def containsWildcardTypes (using Context ) =
434+ existsPart(_.isInstanceOf [WildcardType ], stopAtStatic = true )
435+
432436// ----- Higher-order combinators -----------------------------------
433437
434438 /** Returns true if there is a part of this type that satisfies predicate `p`.
@@ -4461,13 +4465,30 @@ object Types {
44614465 def instantiate (fromBelow : Boolean )(using Context ): Type =
44624466 instantiateWith(avoidCaptures(TypeComparer .instanceType(origin, fromBelow)))
44634467
4468+ /** For uninstantiated type variables: the entry in the constraint (either bounds or
4469+ * provisional instance value)
4470+ */
4471+ private def currentEntry (using Context ): Type = ctx.typerState.constraint.entry(origin)
4472+
44644473 /** For uninstantiated type variables: Is the lower bound different from Nothing? */
4465- def hasLowerBound (using Context ): Boolean =
4466- ! ctx.typerState.constraint.entry(origin).loBound.isExactlyNothing
4474+ def hasLowerBound (using Context ): Boolean = ! currentEntry.loBound.isExactlyNothing
44674475
44684476 /** For uninstantiated type variables: Is the upper bound different from Any? */
4469- def hasUpperBound (using Context ): Boolean =
4470- ! ctx.typerState.constraint.entry(origin).hiBound.isRef(defn.AnyClass )
4477+ def hasUpperBound (using Context ): Boolean = ! currentEntry.hiBound.isRef(defn.AnyClass )
4478+
4479+ /** For uninstantiated type variables: Is the lower bound different from Nothing and
4480+ * does it not contain wildcard types?
4481+ */
4482+ def hasNonWildcardLowerBound (using Context ): Boolean =
4483+ val lo = currentEntry.loBound
4484+ ! lo.isExactlyNothing && ! lo.containsWildcardTypes
4485+
4486+ /** For uninstantiated type variables: Is the upper bound different from Any and
4487+ * does it not contain wildcard types?
4488+ */
4489+ def hasNonWildcardUpperBound (using Context ): Boolean =
4490+ val hi = currentEntry.hiBound
4491+ ! hi.isRef(defn.AnyClass ) && ! hi.containsWildcardTypes
44714492
44724493 /** Unwrap to instance (if instantiated) or origin (if not), until result
44734494 * is no longer a TypeVar
0 commit comments