@@ -301,6 +301,11 @@ object Types {
301301
302302 def isFromJavaObject (using Context ): Boolean = typeSymbol eq defn.FromJavaObjectSymbol
303303
304+ def containsFromJavaObject (using Context ): Boolean = this match
305+ case tp : OrType => tp.tp1.containsFromJavaObject || tp.tp2.containsFromJavaObject
306+ case tp : AndType => tp.tp1.containsFromJavaObject && tp.tp2.containsFromJavaObject
307+ case _ => isFromJavaObject
308+
304309 /** True iff `symd` is a denotation of a class type parameter and the reference
305310 * `<pre> . <symd>` is an actual argument reference, i.e. `pre` is not the
306311 * ThisType of `symd`'s owner, or a reference to `symd`'s owner.'
@@ -4933,8 +4938,23 @@ object Types {
49334938 }
49344939
49354940 def & (that : TypeBounds )(using Context ): TypeBounds =
4936- if ((this .lo frozen_<:< that.lo) && (that.hi frozen_<:< this .hi)) that
4937- else if ((that.lo frozen_<:< this .lo) && (this .hi frozen_<:< that.hi)) this
4941+ // This will try to preserve the FromJavaObjects type in upper bounds.
4942+ // For example, (? <: FromJavaObjects | Null) & (? <: Any),
4943+ // we want to get (? <: FromJavaObjects | Null) intead of (? <: Any),
4944+ // because we may check the result <:< (? <: Object | Null) later.
4945+ if this .hi.containsFromJavaObject
4946+ && (this .hi frozen_<:< that.hi)
4947+ && (that.lo frozen_<:< this .lo) then
4948+ // FromJavaObject in tp1.hi guarantees tp2.hi <:< tp1.hi
4949+ // prefer tp1 if FromJavaObject is in its hi
4950+ this
4951+ else if that.hi.containsFromJavaObject
4952+ && (that.hi frozen_<:< this .hi)
4953+ && (this .lo frozen_<:< that.lo) then
4954+ // Similarly, prefer tp2 if FromJavaObject is in its hi
4955+ that
4956+ else if (this .lo frozen_<:< that.lo) && (that.hi frozen_<:< this .hi) then that
4957+ else if (that.lo frozen_<:< this .lo) && (this .hi frozen_<:< that.hi) then this
49384958 else TypeBounds (this .lo | that.lo, this .hi & that.hi)
49394959
49404960 def | (that : TypeBounds )(using Context ): TypeBounds =
0 commit comments