Skip to content

Commit b0a3bb8

Browse files
committed
Fix overriing check with FromJavaObject
1 parent 87a6f70 commit b0a3bb8

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,12 +1505,33 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
15051505
false
15061506
}
15071507

1508+
// This & will try to preserve the FromJavaObjects type in upper bounds
1509+
// For example, (? <: FromJavaObjects | Null) & (? <: Any),
1510+
// we want to get (? <: FromJavaObjects | Null) intead of (? <: Any),
1511+
// because we may check FromJavaObjects | Null <:< Object | Null later.
1512+
def bounds_&(tp1: TypeBounds, tp2: TypeBounds) =
1513+
if tp1.hi.containsFromJavaObject
1514+
&& (tp1.hi frozen_<:< tp2.hi)
1515+
&& (tp2.lo frozen_<:< tp1.lo) then
1516+
// FromJavaObject in tp1.hi guarantees tp2.hi <:< tp1.hi
1517+
// prefer tp1 if FromJavaObject is in its hi
1518+
tp1
1519+
else if tp2.hi.containsFromJavaObject
1520+
&& (tp2.hi frozen_<:< tp1.hi)
1521+
&& (tp1.lo frozen_<:< tp2.lo) then
1522+
// Similarly, prefer tp2 if FromJavaObject is in its hi
1523+
tp2
1524+
else
1525+
// Use regular & to solve other cases
1526+
tp1 & tp2
1527+
15081528
def isSubArg(arg1: Type, arg2: Type): Boolean = arg2 match {
15091529
case arg2: TypeBounds =>
15101530
val arg1norm = arg1 match {
15111531
case arg1: TypeBounds =>
15121532
tparam match {
1513-
case tparam: Symbol => arg1 & paramBounds(tparam)
1533+
case tparam: Symbol =>
1534+
bounds_&(arg1, paramBounds(tparam))
15141535
case _ => arg1 // This case can only arise when a hk-type is illegally instantiated with a wildcard
15151536
}
15161537
case _ => arg1

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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,6 +4938,8 @@ object Types {
49334938
}
49344939

49354940
def & (that: TypeBounds)(using Context): TypeBounds =
4941+
// if ((that.lo frozen_<:< this.lo) && (this.hi frozen_<:< that.hi)) this
4942+
// else if ((this.lo frozen_<:< that.lo) && (that.hi frozen_<:< this.hi)) that
49364943
if ((this.lo frozen_<:< that.lo) && (that.hi frozen_<:< this.hi)) that
49374944
else if ((that.lo frozen_<:< this.lo) && (this.hi frozen_<:< that.hi)) this
49384945
else TypeBounds(this.lo | that.lo, this.hi & that.hi)

compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,14 @@ object ResolveSuper {
107107
// of the superaccessor's type, see i5433.scala for an example where this matters
108108
val otherTp = other.asSeenFrom(base.typeRef).info
109109
val accTp = acc.asSeenFrom(base.typeRef).info
110-
if (!(otherTp.overrides(accTp, matchLoosely = true)))
110+
// Since the super class can be Java defined,
111+
// we use releaxed overriding check for explicit nulls if one of the symbols is Java defined.
112+
// This forces `Null` being a subtype of reference types during override checking.
113+
val relaxedCtxForNulls =
114+
if ctx.explicitNulls && (sym.is(JavaDefined) || acc.is(JavaDefined)) then
115+
ctx.retractMode(Mode.SafeNulls)
116+
else ctx
117+
if (!(otherTp.overrides(accTp, matchLoosely = true)(using relaxedCtxForNulls)))
111118
report.error(IllegalSuperAccessor(base, memberName, targetName, acc, accTp, other.symbol, otherTp), base.srcPos)
112119

113120
bcs = bcs.tail

0 commit comments

Comments
 (0)